可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I am working on a program that will communicate with various pieces of hardware. Because of the varied nature of the items it communicates and controls, I need to have a different "driver" for each different piece of hardware. This made me think that MEF would be a great way to make those drivers as plugins that can be added even after the product has been released.
I've looked at a lot of examples of how to use MEF, but the question that I haven't been able to find an answer to is how to populate a MEF plugin with external data (eg. from a database). All the examples I can find have the "data" hard-coded into the assembly, like the following example:
[Export( typeof( IRule ) )] public class RuleInstance : IRule { public void DoIt() {} public string Name { get { return "Rule Instance 3"; } } public string Version { get { return "1.1.0.0"; } } public string Description { get { return "Some Rule Instance"; } } }
What if I want Name, Version and Description to come from a database? How would I tell MEF where to get that information?
I may be missing something very obvious, but I don't know what it is.
回答1:
You would have to either pass the information to the plugin after it loaded via properties:
[Export( typeof( IRule ) )] public class RuleInstance : IRule { puliic void DoIt() { } public string Name { get; set; } } public class Program { [Import(typeof( IRule ))] public IRule instance { get; set; } public void Run() { // Load the assemblies here instance.Name = "Rule Instance 3"; } }
Or the plugin could request the variables though a host interface. You can either pass the IHost instance through a property or though a constructor parameter, but constructor parameters are not simple with MEF. Here is through a property:
[Export( typeof( IRule ) )] public class RuleInstance : IRule { puliic void DoIt() { } public void Initialise() { // Load our name from the host, this cannot be done in the constructor string name = Host.GetName(/* some parameters? */) } public IHost Host { get; set; } public string Name { get; set; } } public interface IHost { string GetName(/* some parameters? */); } public class Program : IHost { [Import(typeof( IRule ))] public IRule instance { get; set; } public void Run() { // Load the assemblies here // Make sure the plugins know where the host is... instance.Host = this; } }
You could also "Export" the database interface and "Import" it into any plugins that need database access...
回答2:
You can always export individual values (through contract names), here's an example:
public class Configuration { [Export("SomeValue")] public string SomeValue { get { /* return value from database perhaps? */ } } } [Export(typeof(IRule))] public class RuleInstance : IRule { [Import("SomeValue")] public string SomeValue { get; private set; } }