我应该如何管理类依赖/重构?

时间:2012-10-12 13:36:09

标签: c# .net dependency-injection castle-windsor plugin-architecture

我的应用程序实现了一个模块化架构,可以动态加载一个或多个“插件”程序集。每个程序集都包含一个实现IPlugin接口的类,提供主机应用程序用来与插件交互的各种方法和属性。

这个类不可避免地依赖于插件中的其他类,而这些类可能反过来又有自己的依赖关系。到目前为止,我一直使用Castle Windsor管理所有这些(每个插件包含IWindsorInstaller,我在其中注册其依赖项),并通过其构造函数执行DI。缺点是这些方法必须为public才能使用。

我现在已经意识到并希望通过制作所有这些类internal来锁定插件,但是我不确定处理依赖关系的最佳方法,因为我可能不会能够使用温莎。我不希望这些类实例化它们自己的依赖项(没有松散耦合,缺乏可测试性等),那么还有其他什么方法呢?

2 个答案:

答案 0 :(得分:3)

  

缺点是这种方法必须公开课程   工作。

事实并非如此。你可以注册内部的东西,但你可能会失去Castle Windsor(或任何DI容器)的自动连线(自动构造器注入)功能。您可以通过注册手动创建这些类型的代理来注册内部资源。例如:

container.Register(Component.For<IService>()
    .UsingFactoryMethod(() =>
    {
        var log = container.Resolve<ILogger>();
        return new RealService(log);
    })
    .LifeStyle.Transient);

使用new手动创建服务并不是最理想的,因为自动布线可以使插件的组合根保持最大的可维护性,但我不认为在您的情况下有一个好的替代方案。不过,这比让每个服务创建自己的依赖项(穷人的DI)更好。

<强>更新

我记得一些事情:当您使用泛型方法注册这些内部类型时,应该仍然可以使用内部类型进行自动连接:例如:

container.Register(Component.For<IService>()
    .ImplementedBy<RealService());

要使其正常工作,RealService的构造函数必须是公共的(但RealService本身可以是内部的)。这甚至适用于部分信任,例如在非常严格的Silverlight沙箱中运行时(或者至少,它适用于Simple Injector,但Castle也应该能够这样做)。< / p>

答案 1 :(得分:0)

如果你使用Ninject,你可以为配置绑定的每个程序集添加NinjectModule,然后在宿主应用程序中只需加载模块来注册绑定。

public class ServiceModule : NinjectModule
{
    public override void Load() 
    {
        Bind<IService>().To<RealService>();
    }
}

RealService可以保持在内部,模块可以看到它,因为它位于同一个程序集中。