سؤال

I have sort of plugin architecture in my solution. There is a well-known folder where to place plugins in it. The plugins implement an interface which is shared in the host project.

Initially i load the plugin via Assembly.LoadFrom(fi.FullName).GetTypes() and instanciate the needed type by (IPlugin)Activator.CreateInstance(type);.

So the host (main application) can execute appropriate code implemented by the plugin assembly. This works fine so far.

But recently i tried to implement application logging via NLog and configured NLog in the host project which worked great.

The problem is i would like to use (the already configured) logger in the plugin assembly. If i just reference NLog and use it by LogManager.GetCurrentClassLogger(); there seems to be no configuration set. It does not log to the files i configured in the host project out of the plugin assembly.

I thought of trying to inject an NLogger instance (created in the host project) to a property of the plugin type.

Is this possible or is there a preferred way to accomplish things like that? Thanks

هل كانت مفيدة؟

المحلول

this should work - NLog configuration should work also for the loaded plugin assemblies. The problem is probably related to how your plugins are loaded. Maybe they are in a separate domain (I don't remember how it works) so NLog can't access your main applications's logging configuration.

In that case you could try adding separate nlog configuration files for your plugin assemblies (read nlog documentation about config file naming conventions).

I dont think IOC container will help you in case of dynamically loaded plugins - the container will not know about them so you will have to change the way plugins are loaded and configured. And imho using IOC for configuring nlog is not a great idea.

If the previous options don't work you could try changing the assembly probing path in app.config so your plugins are loaded into the default domain - then NLog should work for these plugins (at least works for me):

<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
  <probing privatePath="Plugins" />
</assemblyBinding>

نصائح أخرى

Have a look at Dependency Injection Containers like Unity or Lightcore.

They are some kind of "component registration stores"

there you can register components to interfaces. Then your consumers just need to request an interface.

The mapping of interface - component can be made in configuration files or source code.

So you can change the mapping without any pain.

For example when they are creating new instances and you are having complextypes as ctor parameters, they can make an automatic lookup if these components are registered and then inject them automatically.

Some Keywords that can help you are "ServiceLocator" "MicroKernel" "Depency Injection"

Components:

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top