Unity:有条件的解决方案

时间:2014-10-28 11:40:40

标签: c# dependency-injection unity-container

我希望使用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;
}

1 个答案:

答案 0 :(得分:2)

你在这里缺少一些抽象。您缺少对数据类型的一般抽象,以及用于创建这些数据类型的实现的抽象:

// 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();
        }
    }
}

您可以看到创建实现的代码已移至工厂。现在剩下的应用程序代码可能是这样的:

// Main flow...outwith bootstrapper
IDataType dt = this.dataTypeFactory.Create(dataRecordType);
dt.ProcessData();

IDataType1IDataType2IDataType3现在只在引导程序中使用并且已经变得多余(或者至少与您提供的代码冗余),因此您甚至可以删除它们全部在一起并将引导逻辑更改为以下内容:

// 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();
        }
    }
}