2013-12-17 44 views
0

我正在写一个应用程序,业务逻辑的各个位可以在单独的组件坐下,然后将这些位被用来建立一个对象希望两个接口,这样的事情:处理与配置的插件与Ninject

public interface ISubjectSource {} 
public interface IStudySource {} 

public class Worker 
{ 
    public Worker(ISubjectSource subjectSource, IStudySource studySource) 
    { 
    .... 
    } 
} 

单独的程序集可以包含各种实现ISubjectSourceIStudySource。然后随着一个配置文件:

"Study1":{ 
    "assemblies":["Compare.Sql.dll"], 
    "mappingSource":"Compare.Sql.SqlSubjectSource,Compare.Sql", 
    "studySource":"Compare.Sql.SqlStudySource,Compare.Sql", 
} 

其中描述了什么是需要建立到工作人员的“Study1”。当各种源具有自己的依赖关系时(例如,Sql Sources接受处理创建连接的字符串可能来自不同文件的连接),我的问题就会到来。因此,我的问题归结为:我如何告诉Ninject,当我为study1创建一个工作者时,确保它获取这些对象,但是当我为Study2创建一个工作者时,它将获得这个另一组对象?

回答

0

下面是我们做什么:

我们已经有了一个接口IPlugin,与标识符和模块的枚举。

public interface IPlugin 
{ 
    string Identification { get; } 

    IEnumerable<Type> Modules { get; } 
} 

模块中的类型必须全部从NinjectModule继承。 Identification是你在你的配置中引用的内容,比如“我想使用插件SQLStudySource”或者“我想使用插件FileStudySource”。

然后我们使用https://github.com/ninject/ninject.extensions.conventions以结合从一组特定的组件的所有IPlugin实现(如在插件文件夹中的所有程序集):在激活

this.Bind(x => x.FromAssembliesInPath("foo") 
      .SelectAllClasses() 
      .InheritedFrom<IPlugin>() 
      .BindTo<IPlugin>()); 

接着插件(或更确切地说及其模块,分别地),根据配置:

IEnumerable<Type> activatedPluginModules = kernel 
    .GetAll<IPlugin>() 
    .Where(plugin => configuration.ActivatedPluginIdentifications.Contains(plugin.Identification) 
    .SelectMany(x => x.Modules) 
    .Distinct(); 

foreach(Type module in activatedPluginModules) 
{ 
    kernel.Load(module); 
} 

就是这样。