另一种管理此依赖关系的方法

时间:2013-01-07 15:42:42

标签: c# dependency-injection ninject

我有一个小类,每次需要时都会创建一个新的数据处理器对象实例。我正在使用注入,但我无法弄清楚如何在不注入IDataProcessingService的情况下获得kernel的激活实例。

有没有更好的方法来做到这一点。我知道我可以制作静态网关而不是注入,但我认为在不同的皮肤中存在同样的问题。

public class DataProcessingManager
{
    private readonly Dictionary<IDataProcessingRequest, IDataProcessingService> _activeProcessingServices;

    private readonly IKernel _kernel;

    public DataProcessingManager(IKernel kernel)
    {
        _kernel = kernel;
        _activeProcessingServices = new Dictionary<IDataProcessingRequest, IDataProcessingService>(new DataProcessingRequestComparer());
    }

    public void ProcessFor(IDataProcessingRequest dataProcessingRequest)
    {
        if (!_activeProcessingServices.ContainsKey(dataProcessingRequest))
        {
            var _processingService = _kernel.Get<IDataProcessingService>();
            _activeProcessingServices.Add(dataProcessingRequest, _processingService);

            _processingService.ProcessingFinished += 
                (sender, args) => _activeProcessingServices.Remove(dataProcessingRequest);

            _processingService.Process(dataProcessingRequest);
        }
    }
}

编辑2:

我必须更改已接受的答案,因为最初建议的实现不是创建我需要的新实例。我知道我可以通过引用内核来使用原始答案,但这不是我想要的。最后,新答案中的.ToFactory()约定是更好的方法。

我将联系该扩展程序的作者并要求他更新代码示例,因为Foo..Bar示例难以阅读。

3 个答案:

答案 0 :(得分:4)

如果您每次都想要一个新实例,可以使用Ninject Factory Extension不依赖于IKernel。

使用此扩展,您可以创建工厂接口来创建IDataProcessingService的实例,但不需要实现该接口。此扩展可以为您实现(在引擎盖下将调用IKernel)。

工厂界面......

public interface IDataProcessingServiceFactory
{
    IDataProcessingService Create();
}

绑定语句(在运行时自动生成工厂实现)...

kernel.Bind<IDataProcessingServiceFactory>().ToFactory();

答案 1 :(得分:1)

如果您不想“依赖”IKernel,您可以创建第二个提供服务的界面:

interface IDataProcessingServiceProvider
{
    IDataProcessingService GetService();
}

然后,您可以让您的内核实现该接口并将其存根以进行测试,而无需实现整个IKernel接口。

答案 2 :(得分:0)

general consensus是让应用程序逻辑依赖于容器或容器抽象是不好的。但是,拥有基础架构组件依赖于容器is fine

但是,请尽量避免将应用程序逻辑与基础结构逻辑混合。诀窍通常是以纯粹的应用程序或纯粹的基础架构的方式提取类。

相关问题