.net – 如何在AutoFac中创建可选的依赖项?
|
我有一个接口,实现和目标: public interface IPerson { public string Name { get; } }
public class Person: IPerson { public string Name { get { return "John"; } } }
public class Target { public Target(IPerson person) {} }
我正在使用Autofac将事物联系在一起: builder.RegisterType<Person>().As<IPerson>().SingleInstance(); 问题是IPerson生活在一个共享程序集中,Person存在于一个插件中(可能存在也可能不存在),而Target存在于加载插件的主应用程序中.如果没有加载实现IPerson的插件,Autofac就无法解决Target的依赖关系而犹豫不决.我不能真的责怪它. 但是我知道Target能够处理缺少IPerson而且非常乐意获得null.事实上,我非常确定依赖于IPerson的所有组件都准备好取而代之.那么我怎么能告诉Autofac-“这是好的,不要担心,只要给我一个空的,好吗?” 我找到的一种方法是向Target添加一个默认参数: public class Target { public Target(IPerson person = null) {} }
这有效,但我需要为所有需要IPerson的组件执行此操作.我可以反过来做吗?不知何故告诉Autofac“如果所有其他方法都无法解析IPerson,请返回null”? 您可以使用以下语法:builder.RegisterType<Target>().WithParameter(TypedParameter.From<IPerson>(null)); 不幸 builder.Register(c => (IPerson)null).As<IPerson>(); // will throw : Autofac.Core.DependencyResolutionException: A delegate registered to create instances of 'ConsoleApplication17.Program+IPerson' returned null. 和 builder.RegisterInstance<IPerson>(null).As<IPerson>(); // will throw : Unhandled Exception: System.ArgumentNullException: Value cannot be null. 如果您不想为每个注册添加WithParameter,则可以添加一个可以为您执行此操作的模块 public class OptionalAutowiringModule : Autofac.Module
{
public OptionalAutowiringModule(IEnumerable<Type> optionalTypes)
{
this._optionalTypes = optionalTypes;
}
public OptionalAutowiringModule(params Type[] optionalTypes)
{
this._optionalTypes = optionalTypes;
}
private readonly IEnumerable<Type> _optionalTypes;
protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry,IComponentRegistration registration)
{
base.AttachToComponentRegistration(componentRegistry,registration);
registration.Preparing += (sender,e) =>
{
e.Parameters = e.Parameters.Concat(new Parameter[] { new OptionalAutowiringParameter(this._optionalTypes) });
};
}
}
public class OptionalAutowiringParameter : Parameter
{
public OptionalAutowiringParameter(IEnumerable<Type> optionalTypes)
{
this._optionalTypes = optionalTypes.ToList();
}
private readonly List<Type> _optionalTypes;
public override Boolean CanSupplyValue(ParameterInfo pi,IComponentContext context,out Func<Object> valueProvider)
{
if (this._optionalTypes.Contains(pi.ParameterType) && !context.IsRegistered(pi.ParameterType))
{
valueProvider = () => null;
return true;
}
else
{
valueProvider = null;
return false;
}
}
}
然后,您所要做的就是使用可选的依赖项注册模块 builder.RegisterModule(new OptionalAutowiringModule(typeof(IPerson))); 但不是注入可能导致nullReferenceException的null引用.另一种解决方案是创建NullPerson实现. builder.RegisterType<NullPerson>().As<IPerson>(); builder.RegisterType<Target>(); 如果您的实际实现仅重新注册,它将覆盖原始实现. (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
