c# - 传递 Ninject 内核是一个好习惯吗?

标签 c# ninject

我正在编写一个执行几个任务的小型框架。 有些任务需要通过 Ninject 注入(inject)的特定属性。

假设我的基类中有以下表示单个任务的构造函数:

protected DDPSchedulerTask(ILogger logger, List<string> platforms, IBackOfficeDataStore backOfficeDataStore, ICommonDataStore commonDataStore)
{
    _logger = logger;
    _platforms = platforms;
    _backOfficeDataStore = backOfficeDataStore;
    _commonDataStore = commonDataStore;
}

所有任务都需要这些属性,因此我使用带有以下 Ninject 模块的 Ninject 注入(inject)它们。

public class DDPDependencyInjectionBindingConfiguration : NinjectModule
{
    #region NinjectModule Members

    /// <summary>
    ///     Loads the module into the kernel.
    /// </summary>
    public override void Load()
    {
        Bind<Scheduler>().ToSelf(); // Make sure that the 'Scheduler' is resolved to itself.
        Bind<ILogger>().ToMethod(context => LogFactory.Create()); // Make sure that an instance of an ILogger is created through the LogFactory.

        // Straightforward binding.
        Bind<ICommonDataStore>().To<Common>();
        Bind<IBackOfficeDataStore>().To<BtDbInteract>();
        Bind<IDirectoryResolver>().To<Demo>();
    }

    #endregion
}

如果链中的第一个条目需要由 Ninject 解决,我的调度程序对象本身,所以我通过 Ninject 手动解决这个问题。

var schedulerInstance = kernel.Get<Scheduler>();

现在,我的调度程序有一个方法可以将任务添加到列表中,而不是使用 Ninject:

var tasksList = new List<DDPSchedulerTask>
{
    new AWNFileGeneratorTask(_logger, availablePlatforms, _backOfficeDataStore, _commonDataStore)
};

然后,所有这些任务都被执行了。 现在,其中一些任务确实需要额外的依赖项,我想通过 Ninject 解决这些问题,但我应该怎么做?

在任务中,我创建了一个具有 Inject 属性的属性,但该对象保持为空。

[Inject]
private IDirectoryResolver directoryResolver { get; set; }

有人知道如何解决这个问题吗?

我可以将内核传递给不同的任务,但有些东西告诉我这不是正确的方法。

亲切的问候

最佳答案

你应该利用Ninject.Extensions.Factory .

只需创建一个代表您的任务工厂的界面。然后将信息传递给作为工厂的 Ninject,他将为您创建此接口(interface)的完整实现。

using System;
using System.Collections.Generic;
using Ninject;
using Ninject.Extensions.Factory;

internal class Program
{
    public static void Main(string[] args)
    {
        IKernel ninjectKernel = new StandardKernel();

        ninjectKernel.Bind<DDPSchedulerTask>().ToSelf();
        ninjectKernel.Bind<AWNFileGeneratorTask>().ToSelf();
        ninjectKernel.Bind<IDirectoryResolver>().To<DirectoryResolver>();
        ninjectKernel.Bind<ITaskFactory>().ToFactory();

        var mainTask = ninjectKernel.Get<DDPSchedulerTask>();
        mainTask.CreateDbSchedulerTask();
        mainTask.CreateAwnFileTask();

        Console.ReadLine();
    }
}

public interface ITaskFactory
{
    TTask CreateTask<TTask>() where TTask : DDPSchedulerTask;
}

public class DDPSchedulerTask
{
    private readonly ITaskFactory _tasksFactory;
    private readonly List<DDPSchedulerTask> _tasksList;

    public DDPSchedulerTask(ITaskFactory tasksFactory)
    {
        _tasksFactory = tasksFactory;

        _tasksList = new List<DDPSchedulerTask>();
    }

    public void CreateAwnFileTask()
    {
        var task = _tasksFactory.CreateTask<AWNFileGeneratorTask>();
        _tasksList.Add(task);
    }

    public void CreateDbSchedulerTask()
    {
        var task = _tasksFactory.CreateTask<DDPSchedulerTask>();
        _tasksList.Add(task);
    }
}

public class AWNFileGeneratorTask : DDPSchedulerTask
{
    [Inject]
    public IDirectoryResolver DirectoryResolver { get; set; }

    public AWNFileGeneratorTask(ITaskFactory tasksFactory)
        : base(tasksFactory)
    {
    }
}

public interface IDirectoryResolver
{
}

public class DirectoryResolver : IDirectoryResolver
{
}

@gisek 如前所述,通过属性注入(inject) Giseke 依赖项并不是最佳解决方案。您还可以在此示例中使用构造函数注入(inject)。

public class AWNFileGeneratorTask : DDPSchedulerTask
{
    private IDirectoryResolver _directoryResolver;

    public AWNFileGeneratorTask(ITaskFactory tasksFactory, IDirectoryResolver directoryResolver)
        : base(tasksFactory)
    {
        _directoryResolver = directoryResolver;
    }
}

额外参数注入(inject):

public interface ITaskFactory
{
    DDPSchedulerTask CreateDDPSchedulerTask();
    AWNFileGeneratorTask CreateAWNFileGeneratorTask(string extraParam);
}

public class AWNFileGeneratorTask : DDPSchedulerTask
{
    private IDirectoryResolver _directoryResolver;
    private string _extraParam;

    public AWNFileGeneratorTask(ITaskFactory tasksFactory, IDirectoryResolver directoryResolver,
        string extraParam)
        : base(tasksFactory)
    {
        _extraParam = extraParam;
        _directoryResolver = directoryResolver;
    }
}

public void CreateAwnFileTask()
{
    var task = _tasksFactory.CreateAWNFileGeneratorTask("extra");
    _tasksList.Add(task);
}

关于c# - 传递 Ninject 内核是一个好习惯吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30527596/

相关文章:

c# - 带有 Windows 身份验证和 SSL 的 WCF

c# - 使用其 setter 捕获属性更改

c# - ServicePointManager.ServerCertificateValidationCallback 的目的是什么?

asp.net-mvc - Ninject DI 导致部署问题

.net - Ninject - 拦截多重绑定(bind)解析

c# - AllowUserToAddRows 不适用于 DataGridView 上的 List<> 数据源

c# - 使用 LINQ 计算 Lists int C# Dictionary 的平均值

c# - Ninject 默认上下文绑定(bind)

asp.net - 在新线程中使用 Ninject

asp.net - Ninject、ASP.NET 和自定义控件