更改依赖关系链中的最低级别

时间:2016-10-25 07:38:50

标签: c# dependency-injection unity-container

在我的项目中,我有5个班级:

  • ClassA (实现接口 IClassA ),将 IClassC 作为构造函数的参数
  • ClassB (实现接口 IClassB ),将 IClassC 作为构造函数的参数
  • ClassC (实现接口 IClassC ),将 IClassD 作为构造函数的参数
  • ClassD1 ClassD2 (均实现接口 IClassD

Unity容器的配置如下:

    container.RegisterType<IClassA, ClassA>(new HierarchicalLifetimeManager());
    container.RegisterType<IClassB, ClassB>(new HierarchicalLifetimeManager());
    container.RegisterType<IClassC, ClassC>(new HierarchicalLifetimeManager());
    container.RegisterType<IClassD, ClassD1>(nameof(ClassD1), new HierarchicalLifetimeManager());
    container.RegisterType<IClassD, ClassD2>(nameof(ClassD2), new HierarchicalLifetimeManager());

我想配置我的项目:

  • IClassA 正在使用 ClassC ,它正在使用 ClassD1
  • IClassB 正在使用 ClassC ,它正在使用 ClassD2

我猜我应该在注册 IClassA IClassB 时改变一些东西。我想避免更改 IClassC 注册。

这可能吗?

1 个答案:

答案 0 :(得分:0)

我不知道你想要这样做的确切原因,但可以在工厂的帮助下完成。

虽然它有效,但我可能会审查设计和环境,因为它很复杂,它会让开发人员感到困惑(闻起来有点气味)。

class Program
{
    static void Main(string[] args)
    {
        IUnityContainer container = new UnityContainer();

        container.RegisterType<IClassC, ClassC>();
        container.RegisterType<IClassD, ClassD1>(nameof(ClassD1), new HierarchicalLifetimeManager());
        container.RegisterType<IClassD, ClassD2>(nameof(ClassD2), new HierarchicalLifetimeManager());
        container.RegisterType<IClassA, ClassA>(new InjectionConstructor(Factory.GetClassC<ClassD1>(container)));
        container.RegisterType<IClassB, ClassB>(new InjectionConstructor(Factory.GetClassC<ClassD2>(container)));

        var classA = container.Resolve<IClassA>();
        var classB = container.Resolve<IClassB>();

        classA.HelloFromA();
        classB.HelloFromB();
    }
}

public class Factory
{
    public static IClassC GetClassC<TClassD>(IUnityContainer container)
        where TClassD : IClassD
    {
        return container.Resolve<IClassC>(new DependencyOverride<IClassD>(
            container.Resolve<IClassD>(typeof(TClassD).Name)));
    }
}

public interface IClassA
{
    void HelloFromA();
}

public interface IClassB
{
    void HelloFromB();
}

public interface IClassC
{
    void HelloFromC();
}

public interface IClassD { }

public class ClassA : IClassA
{
    private readonly IClassC _classC;
    public ClassA(IClassC classC)
    {
        _classC = classC;
    }
    public void HelloFromA()
    {
        _classC.HelloFromC();
    }
}

public class ClassB : IClassB
{
    private readonly IClassC _classC;
    public ClassB(IClassC classC)
    {
        _classC = classC;
    }

    public void HelloFromB()
    {
        _classC.HelloFromC();
    }
}

public class ClassC : IClassC
{
    private readonly IClassD _classD;
    public ClassC(IClassD classD)
    {
        _classD = classD;
    }

    public void HelloFromC()
    {
        Console.WriteLine(string.Format("Hello with {0}", _classD.GetType().Name));
    }
}

public class ClassD1 : IClassD
{
}

public class ClassD2 : IClassD
{
}

注意事项:

  1. 注意注册顺序。 ClassA和ClassB最后注册,
  2. HierarchicalLifetimeManager不能在此实例中使用,因为您需要同一类的2个不同实例。
  3. 考虑阅读这篇文章: http://sharpfellows.com/post/Unity-IoC-Container-