在Unity容器中将null注册为实例

时间:2012-07-09 09:50:37

标签: c# .net unity-container

我有一个带有可选依赖项的存储库类:

class MyRepository : BaseRepository, IMyRepository
{
    public MyRepository(IDataContext dataContext, ICacheProvider cacheProvider = null)
        : base(dataContext, cacheProvider)
    {}

    // …
}

cacheProvider参数的存在充当存储库的策略。 我想要像这样设置Unity容器:

Container.RegisterType<IDataContext, MyDataContext>(new PerResolveLifetimeManager(), new InjectionConstructor())
         .RegisterInstance<ICacheProvider>(null) // ???
         .RegisterType<IMyRepository, MyRepository>();

即。没有为MyRepository指出具有一个参数的特定InjectionConstructor,而是使用带有null的默认构造函数作为 cacheProvider 参数。

有没有办法做到这一点?

5 个答案:

答案 0 :(得分:20)

我发现RegisterType而不是Register实例支持返回null。

container.RegisterType<IInterface>(new InjectionFactory((c) => null));

这是获得实际null的最简单方法。

答案 1 :(得分:9)

.RegisterType<IMyRepository, MyRepository>()来电中,使用InjectionConstructor指定OptionalParameter,如

.RegisterType<IMyRepository, MyRepository>(new InjectionConstructor(
new ResolvedParameter<IDataContext>(), 
new OptionalParameter<ICacheProvider>()));

答案 2 :(得分:5)

对于'很高兴拥有'依赖关系,你应该使用属性注入而不是ctor注入。 Config看起来像这样:

public class MyRepository
{
  public ICacheProvider Cache { get; set; }
}

container.RegisterType<MyRepository>(new InjectionProperty("Cache", typeof(ICacheProvider)));

这会将ICacheProvider的实现注入到Cache的{​​{1}}个属性中。由于您必须在存储库类中调用MyRepository属性的任何地方实现空检查,我将使用@ dtryon的提议并实现Cache。这样更方便,更不容易出错。

答案 3 :(得分:2)

最简单的过时解决方案

目前已经不建议使用InjectionFactory调用RegisterType,因此建议使用以下方法:

container.RegisterFactory<ITypeToResolve>(c => null);

灵活的扩展方式

或者,如果您想使用扩展方法返回想要的任何内容,则可以执行以下操作:

public static void RegisterFactory<TToResolve>(IUnityContainer container, Func<TToResolve> factory) => 
        container.RegisterFactory<TToResolve>(c => factory.Invoke());

然后消耗您要做的事:

container.RegisterFactory<ITypeToResolve>(() => new MyTypeToResolve());

答案 4 :(得分:0)

我最终在我的可选依赖项上实现了某种NullObject模式:

public class NullCacheProvider : ICacheProvider
{
    // …
}

在基础知识库类中,我检查了一下:

public class BaseRepository
{
    protected readonly ICacheProvider CacheProvider;
    protected readonly bool ShouldUseCache;

    protected BaseRepository(IDataContext context, ICacheProvider cacheProvider)
    {
        CacheProvider = cacheProvider;
        ShouldUseCache = 
            CacheProvider != null && !(CacheProvider is NullCacheProvider);
    }
}

然后在我不需要缓存的项目中,我已经像这样配置了Unity:

container
    .RegisterType<IDataContext, MyDataContext>(new PerResolveLifetimeManager(), new InjectionConstructor())
    .RegisterType<ICacheProvider, NullCacheProvider>() 
    .RegisterType<IMyRepository, MyRepository>();

所有这一点的重点在于,特定存储库可能根据存在的可选依赖性的不同而采取不同的行为。它可能看起来像一些架构缺陷,但解决方案符合我的要求。