Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/260.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 统一:条件分解_C#_Dependency Injection_Unity Container - Fatal编程技术网

C# 统一:条件分解

C# 统一:条件分解,c#,dependency-injection,unity-container,C#,Dependency Injection,Unity Container,我希望使用Unity根据收到的特定数据在运行时解析类型。我的代码(与下面显示的代码类似)当前在启动时在引导程序类中注册类型,然后在主流中决定需要什么类型 我想做的是用解析器替换使用“new”关键字的代码行,然而,由于这段代码已经超出了我的引导程序,我不确定如何做到这一点……我是Unity的新手,所以请轻松一点 // In Bootstrapper class resolver.RegisterType<IDataType1, DataType1>(); resolver.Regist

我希望使用Unity根据收到的特定数据在运行时解析类型。我的代码(与下面显示的代码类似)当前在启动时在引导程序类中注册类型,然后在主流中决定需要什么类型

我想做的是用解析器替换使用“new”关键字的代码行,然而,由于这段代码已经超出了我的引导程序,我不确定如何做到这一点……我是Unity的新手,所以请轻松一点

// In Bootstrapper class
resolver.RegisterType<IDataType1, DataType1>();
resolver.RegisterType<IDataType2, DataType2>();
resolver.RegisterType<IDataType3, DataType3>();


// Main flow...outwith bootstrapper
switch (dataRecordType)
{
    case DataRecordType.dataType1:
        DataType1 dt1 = new DataType1();
        dt1.ProcessData();
        break;

    case DataRecordType.dataType2:
        DataType2 dt2 = new DataType2();
        dt2.ProcessData();
        break;

    case DataRecordType.dataType3:
        DataType3 dt3 = new DataType3();
        dt3.ProcessData();
        break;

    default:
        break;
}
//在引导程序类中
resolver.RegisterType();
resolver.RegisterType();
resolver.RegisterType();
//主流…用引导器输出
开关(数据记录类型)
{
案例DataRecordType.dataType1:
DataType1 dt1=新的DataType1();
dt1.ProcessData();
打破
案例DataRecordType.dataType2:
DataType2 dt2=新的DataType2();
dt2.ProcessData();
打破
案例DataRecordType.dataType3:
DataType3 dt3=新的DataType3();
dt3.ProcessData();
打破
违约:
打破
}

这里缺少一些抽象概念。您缺少对数据类型的一般抽象和创建这些数据类型的实现的抽象:

// In your core layer
public interface IDataType {
    void ProcessData();
}

public interface IDataTypeFactory {
    IDataType Create(DataRecordType dataRecordType);
}

// In Bootstrapper class
resolver.RegisterInstance<IDataTypeFactory>(new DataTypeFactory(resolver));
resolver.RegisterType<IDataType1, DataType1>();
resolver.RegisterType<IDataType2, DataType2>();
resolver.RegisterType<IDataType3, DataType3>();

private sealed class DataTypeFactory : IDataTypeFactory {
    private readonly IUnityContainer container;
    public DataTypeFactory(IUnityContainer container) {
        this.container = container;
    }

    public IDataType Create(DataRecordType dataRecordType) {
        switch (dataRecordType) {
            case DataRecordType.dataType1:
                return this.container.Resolve<IDataType1>();
            case DataRecordType.dataType2:
                return this.container.Resolve<IDataType2>();
            case DataRecordType.dataType3:
                return this.container.Resolve<IDataType3>();
            default:
                throw new InvalidEnumArgumentException();
        }
    }
}
IDataType1
IDataType2
IDataType3
现在仅在引导程序中使用,并且已变得冗余(或者至少与您提供的代码冗余),因此您甚至可以将它们一起删除,并将引导逻辑更改为以下内容:

// In Bootstrapper class
resolver.RegisterInstance<IDataTypeFactory>(new DataTypeFactory(resolver));
resolver.RegisterType<DataType1>();
resolver.RegisterType<DataType2>();
resolver.RegisterType<DataType3>();

private sealed class DataTypeFactory : IDataTypeFactory {
    private readonly IUnityContainer container;
    public DataTypeFactory(IUnityContainer container) {
        this.container = container;
    }

    public IDataType Create(DataRecordType dataRecordType) {
        switch (dataRecordType) {
            case DataRecordType.dataType1:
                return this.container.Resolve<DataType1>();
            case DataRecordType.dataType2:
                return this.container.Resolve<DataType2>();
            case DataRecordType.dataType3:
                return this.container.Resolve<DataType3>();
            default:
                throw new InvalidEnumArgumentException();
        }
    }
}
//在引导程序类中
resolver.RegisterInstance(新的DataTypeFactory(resolver));
resolver.RegisterType();
resolver.RegisterType();
resolver.RegisterType();
私有密封类DataTypeFactory:IDataTypeFactory{
专用只读IUnityContainer容器;
公共数据类型工厂(IUnityContainer容器){
this.container=容器;
}
公共IDataType创建(DataRecordType DataRecordType){
开关(数据记录类型){
案例DataRecordType.dataType1:
返回此.container.Resolve();
案例DataRecordType.dataType2:
返回此.container.Resolve();
案例DataRecordType.dataType3:
返回此.container.Resolve();
违约:
抛出新的InvalidEnumArgumentException();
}
}
}

+1值得一提的是,IOC容器不应遗漏合成根(因为OP似乎是初学者)。还有一种方法,我们可以创建一个工厂,而无需将代码与
容器耦合。解析
?@SriramSakthivel:感谢您的注意。我同意,容器不应该被引用到任何地方,除了复合根。可以将工厂与容器解耦,但由于此工厂实现可以是Composition根的一部分,因此工厂引用容器本身没有问题。但是另一种选择是将
DataTypeX
类注入工厂而不是容器。我想您的意思是将
Func
注入工厂?否则,我们需要多个工厂实例来获取新的
DataTypeX的实例,不是吗?@SriramSakthivel:不是。我的意思是要有一个具有以下构造函数的工厂:
DataTypeFactory(DataType1 dt1,DataType2 dt2,DataType3 dt3)
。是的,但是您的工厂将始终返回相同的实例。这改变了人们的行为,对吗?为了实现当前行为(瞬态),我们需要
DataTypeFactory(Func dt1,Func dt2,…)
如果我错了,请纠正我。我是autofac用户,默认生存期是每个依赖项的实例数,这就是我问这个问题的原因:)
// In Bootstrapper class
resolver.RegisterInstance<IDataTypeFactory>(new DataTypeFactory(resolver));
resolver.RegisterType<DataType1>();
resolver.RegisterType<DataType2>();
resolver.RegisterType<DataType3>();

private sealed class DataTypeFactory : IDataTypeFactory {
    private readonly IUnityContainer container;
    public DataTypeFactory(IUnityContainer container) {
        this.container = container;
    }

    public IDataType Create(DataRecordType dataRecordType) {
        switch (dataRecordType) {
            case DataRecordType.dataType1:
                return this.container.Resolve<DataType1>();
            case DataRecordType.dataType2:
                return this.container.Resolve<DataType2>();
            case DataRecordType.dataType3:
                return this.container.Resolve<DataType3>();
            default:
                throw new InvalidEnumArgumentException();
        }
    }
}