延迟加载可选的依赖属性抛出解析异常
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 块。
我使用 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 块。