3

我有一个小类,每次需要它时都会创建一个数据处理器对象的新实例。我对所有事情都使用了注入,但我无法弄清楚如何在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示例难以阅读。

4

3 回答 3

4

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

使用此扩展,您可以创建工厂接口来创建 IDataProcessingService 的实例,但您不需要实现该接口。这个扩展可以为你实现它(它会在后台调用 IKernel)。

出厂界面...

public interface IDataProcessingServiceFactory
{
    IDataProcessingService Create();
}

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

kernel.Bind<IDataProcessingServiceFactory>().ToFactory();
于 2013-01-07T16:32:17.340 回答
1

如果您不想“依赖” IKernel,您可以创建第二个接口来提供服务:

interface IDataProcessingServiceProvider
{
    IDataProcessingService GetService();
}

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

于 2013-01-07T15:50:51.497 回答
0

普遍的共识是,让应用程序逻辑依赖于容器或容器抽象是不好的。但是,让基础设施组件依赖于容器是可以的。

但是,请尽量避免将应用程序逻辑与基础架构逻辑混在一起。诀窍通常是以一种可以是纯应用程序或纯基础设施的方式提取类。

于 2013-01-07T16:08:57.310 回答