团结:有条件的解决

本文关键字:解决 有条件 团结 | 更新日期: 2023-09-27 18:28:02

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

团结:有条件的解决

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

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