延迟加载可选的依赖属性抛出解析异常

Lazy loading of optionally dependent properties throws resolution exception

我使用 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] 应该处理这种情况。

似乎 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 为 null.. 写入控制台。

然而,在代码稍有机会后(将 public Bar 更改为 public Lazy<Bar> 并将 Bar == null 更改为 Bar == null || Bar.Value == null)调用 Bar.Value 会抛出一个 Unity异常。

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