19

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

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参数的默认构造函数。

有没有办法做到这一点?

4

5 回答 5

27

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

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

这是获得实际null返回的最直接的方法。

于 2013-05-07T01:44:59.457 回答
11

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

.RegisterType<IMyRepository, MyRepository>(new InjectionConstructor(
new ResolvedParameter<IDataContext>(), 
new OptionalParameter<ICacheProvider>()));
于 2012-07-10T10:48:44.317 回答
6

对于“很高兴拥有”依赖项,您应该使用属性注入而不是 ctor 注入。配置看起来像这样:

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

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

这会将 的实现注入ICacheProvider到名为Cache您的MyRepository. 因为无论您在什么地方调用Cache存储库类中的属性,您都必须实施空检查,所以我将采用@dtryon 的提议并实施NullCacheProvider. 这更方便,更不容易出错。

于 2012-07-09T10:21:15.347 回答
4

最简单的非过时解决方案

使用 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());
于 2019-09-20T00:01:24.780 回答
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>();

所有这一切的重点是特定存储库可能会根据可选依赖项的存在事实而采取不同的行动。这似乎是一些架构缺陷,但该解决方案符合我的要求。

于 2012-07-10T10:38:55.323 回答