首页 > 解决方案 > 多链依赖,其中一些需要运行时参数

问题描述

我正在使用 Castle Windsor 为 Web 服务项目设置依赖注入。我有一些依赖于运行时参数的类,它们也是其他类的依赖项。对于这个问题,我有一个可行的解决方案,但是随着运行时参数的依赖链变长,它会变得混乱。我正在尝试实施更优雅的解决方案。

我使用我正在注册的 TypedFactoryFacility 解决了其中一些依赖项,如下所示:

public interface ISomeClassFactory
{
   ISomeClass Create(ISomeSimpleDependency dependency);
}

...

public interface ISomeSimpleDependencyFactory
{
   ISomeSimpleDependency Create(string runtimeArgument);
}

...

public void Install(IWindsorContainer container, IConfigurationStore store)
{
    container.Register(
        Component.For<ISomeClass>().ImplementedBy<SomeClass>(),
        Component.For<ISomeClassFactory().AsFactory());
    container.Register(
        Component.For<ISomeSimpleDepencency>().ImplementedBy<SomeSimpleDependency>(),
        Component.For<ISomeSimpleDepencencyFactory().AsFactory());
}

并像这样调用:

public void WebServiceMethod(string runtimeArgument)
{
    ISomeSimpleDependency someSimpleDependency = container.Resolve<ISomeSimpleDependencyFactory>().Create(runtimeArgument);
    ISomeClass someClass = container.Resolve<ISomeSimpleClassFactory>().Create(someSimpleDependency);
    // the rest of the method
}

Thgis 有效,但存在一些问题。即使我不需要在 someSimpleDependency 上调用任何方法,我也必须实例化它以使其作为 someClass 的依赖项(这是我试图通过在该项目中实现依赖注入来解决的原始问题)。此外,当我有一个具有运行时依赖项的类时,事情变得更加棘手,该依赖项在依赖链中向下几层:

ISomeClass -> IDependency1 -> IDependency2 -> IDependency3 -> runtimeArgument

有没有办法在没有工厂方法从依赖项 3 链接起来的情况下实例化 someClass?

public void WebServiceMethod(string runtimeArgument)
{
    IDependency3 dependency3= container.Resolve<IDependency3Factory>().Create(runtimeArgument);
    IDependency2 dependency2 = container.Resolve<IDependency2Factory>().Create(dependency3);
    IDependency1 dependency1 = container.Resolve<IDependency1Factory>().Create(dependency2);

    ISomeClass someClass = container.Resolve<ISomeClassFactory>().Create(dependency1);

}

标签: c#dependency-injectioninversion-of-controlcastle-windsor

解决方案


我不确定这是否是解决此问题的最佳解决方案,但我能够使用Scoped Lifestyle获得可行的解决方案。

public void Install(IWindsorContainer container, IConfigurationStore store)
{
    container.Register(Component.For<ISomeClass>().ImplementedBy<SomeClass>());
    container.Register(Component.For<IDependency1>().ImplementedBy<Dependency1>());
    container.Register(
        Component.For<ISomeSimpleDepencency>().ImplementedBy<ISomeSimpleDepencency>().LifeStyleScoped(),
        Component.For<ISomeSimpleDepencencyFactory().AsFactory());
}

并在调用方法中

public void WebServiceMethod(string runtimeArgument)
{
    using (container.BeginScope())
    {
        IDependency3 dependency3= container.Resolve<ISomeSimpleDepencencyFactory>().Create(runtimeArgument);

        ISomeClass someClass = container.Resolve<ISomeClass>());
    }
}

使用运行时参数的实例将保留在范围内。我没有将此标记为答案,因为我还不相信没有更好的解决方案


推荐阅读