我正在使用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]
应该处理这个确切的情况。
答案 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块。