Unity IoC:“操作可能会破坏运行时的稳定性”

时间:2013-10-25 16:37:20

标签: dependency-injection inversion-of-control unity-container

是否可以在UnityContainer中配置的另一种类型的构造函数中实例化UnityContainer中配置的类型?根据我目前的解决方案,我得到了一个

  

ResolutionFailedException:
  依赖项的解析失败,type =“Sample.IMyProcessor”,name =“(none)”   在解决时发生例外情况。
  例外情况是:VerificationException - 操作可能会破坏运行时的稳定性。

问题是我的第二个类( FileLoader )有一个应该在第一个构造函数中计算的参数:

MyProcessor 类的构造函数:

public class MyProcessor : IMyProcessor
{
    private readonly IFileLoader loader;
    private readonly IRepository repository;

    public MyProcessor(IRepository repository, string environment, Func<SysConfig, IFileLoader> loaderFactory)
    {
        this.repository = repository;
        SysConfig config = repository.GetConfig(environment);

        loader = loaderFactory(config);
    }

    public void DoWork()
    {
        loader.Process();
    }
}

这里是UnityContainer配置的主要功能:

public static void Run()
{
    var unityContainer = new UnityContainer()
    .RegisterType<IRepository, MyRepository>()
    .RegisterType<IFileLoader, FileLoader>()
    .RegisterType<IMyProcessor, MyProcessor>(new InjectionConstructor(typeof(IRepository), "DEV", typeof(Func<SysConfig, IFileLoader>)));

    //Tests
    var x = unityContainer.Resolve<IRepository>(); //--> OK
    var y = unityContainer.Resolve<IFileLoader>(); //--> OK

    var processor = unityContainer.Resolve<IMyProcessor>();
    //--> ResolutionFailedException: "Operation could destabilize the runtime."

    processor.DoWork();
}

FileLoader 类:

public class FileLoader : IFileLoader
{
    private readonly SysConfig sysConfig;

    public FileLoader(SysConfig sysConfig, IRepository repository)
    {
        this.sysConfig = sysConfig;
    }

    public void Process()
    {
        //some sample implementation
        if (sysConfig.IsProduction)
            Console.WriteLine("Production Environement");
        else
            Console.WriteLine("Test Environment");
    }
}

我认为问题与传递给MyProcessor类的 Func 有关。还有另一种方法可以将 loaderFactory 传递给 MyProcessor 类吗?

谢谢!

1 个答案:

答案 0 :(得分:5)

问题是Unity自动工厂仅支持Func<T>而不支持任何其他Func泛型。

您可以使用Unity注册所需的Func,然后它将被解析:

Func<SysConfig, IFileLoader> func = config => container.Resolve<IFileLoader>();
container.RegisterType<Func<SysConfig, IFileLoader>>(new InjectionFactory(c => func));

var processor = container.Resolve<IMyProcessor>();

还有一些其他解决方案,例如:Unity's automatic abstract factory