延迟加载可选的依赖属性会引发解决方案异常

时间:2015-09-14 14:48:59

标签: c# lazy-loading unity-container

我正在使用Unity来确保我的应用程序松散耦合。

我需要在我的一个类上使用延迟加载可选属性。我已使用[OptionalDependency]属性标记了此属性。

当该属性确实已在Unity注册时,我的代码工作正常,我可以从属性中获取值。我希望该属性包含null如果属性尚未注册(据我所知使用OptionalDependency导致Unity禁止它自己的异常)......但事实并非如此。我得到一个典型的Unity异常,因为它无法解析接口类型。

我是否认为OptionalDependency不能与Lazy一起使用,或者我错过了某些内容(使用Unity或Lazy类)?

以下是我目前正在处理的代码示例:

    [OptionalDependency]
    public Lazy<IEventCollection<T>> EventCollection { get; set; }

    public IEnumerable<IEvent<T>> Events
    {
        get
        {
            if (EventCollection != null && EventCollection.Value != null)  //Exception thrown on this line
                return EventCollection.Value.Events;
            else
                return null;
        }
    }

确切的例外情况如下:

Resolution of the dependency failed, type = "IEventCollection`1[ComponentType]", name = "(none)".

Exception occurred while: while resolving.

Exception is: InvalidOperationException - The current type, IEventCollection`1[ComponentType], is an interface and cannot be constructed. Are you missing a type mapping?

-----------------------------------------------

At the time of the exception, the container was:



  Resolving IEventCollection`1[ComponentType],(none)

就像我写的那样 - 这是Unity在尝试解析尚未注册的接口映射时抛出的标准异常。再次 - 我的理解是[OptionalDependency]应该处理这个确切的情况。

1 个答案:

答案 0 :(得分:0)

Unity(至少版本3.5.1404.0)确实存在[OptionalDependency]Lazy的问题。

考虑以下示例:

    public interface IFoo
    {
        void Operation();
    }

    public class Foo : IFoo
    {
        [OptionalDependency]
        public Bar Bar { get; set; }

        public void Operation()
        {
            if (Bar == null)
                Console.Write("Bar is null..");
            else
                Console.Write("Bar isn't null!");
        }
    }

    (...)

    container.RegisterType<IFoo, Foo>(); //container is an IUnityContainer
    var fooInstance = container.Resolve<IFoo>();
    fooInstance.Operation();

上面的代码将按预期运行 - 调用测试操作而不注册Bar将导致 Bar为空... 写入控制台。

但是,在稍微有机会使用代码(将public Bar更改为public Lazy<Bar>并将Bar == null更改为Bar == null || Bar.Value == null)之后,调用Bar.Value会引发Unity异常。

唯一的方法是在Bar.Value周围手动设置try-catch块。