在标准应用程序中注入自定义代码

本文关键字:自定义 代码 注入 标准 应用程序 | 更新日期: 2023-09-27 18:04:36

我们公司有一个标准的应用程序。现在我想在应用程序中注入一些自定义程序集。

通常情况下,如果你有一个ninject内核或unity容器,你可以得到如下实现:

IKernel kernel = new StandardKernel();
DealerService myServ = new DealerService(kernel.Get<IDealerController>());

DealerService:

public partial class DealerService : ServiceBase
{
    private readonly IDealerController Controller;
    public DealerService(IDealerController controller)
    {
        Controller = controller;
        InitializeComponent();
    }
    protected override void OnStart(string[] args)
    {
        Process();
    }
    protected override void OnStop()
    {
    }
    public void Process()
    {
        Controller.GetDealerDetails(5);
    }
}

DealerController接口

public interface IDealerController
{
    Dealer GetDealerDetails(int dealerId);
}

经销商控制器的实现:

public class DealerController : IDealerController
{
    public Dealer GetDealerDetails(int dealerId)
    {     
        throw new NotImplementedException("This is a custom error thrown from the controller implementation");
    }
}

现在的事情是,我不希望标准应用程序知道自定义程序集。dealerservice是一个工作流活动,可以通过工作流基础动态地找到它。问题是注入的DealerController是空的…如何在没有kernel.Get<IDealerController>()行的情况下在标准应用程序中注入IDealerController的实现?

如果你使用Ninject和Ninject MVC 3 nuget包,实现被注入到MVC控制器的构造函数中,而不调用kernel.Get<IDealerController>()

编辑:

添加了具有相同程序集名称的模块Ninject.Extensions.Controllers.Module,以便通过命名约定找到该模块。这在Ninject文档中有描述。这在我的MVC应用程序中工作。

public class ControllersModule : NinjectModule
{
    public override void Load()
    {            
        this.Bind<IDealerController>().To<DealerController>();            
    }
}

在标准应用程序中注入自定义代码

如果你想把IDealerController的实现注入到DealerService中,你还必须让Ninject来管理DealerService的实例化。

IKernel kernel = new StandardKernel();
kernel.Bind<IDealerController>.To<DefaultDealerController>(); //.InSingletonScope();
kernel.Bind<DealerService>().ToSelf(); //.InSingletonScope();
DealerService myServ = kernel.Get<DealerService>();

要动态加载Ninject配置,可以使用模块方法和kernel.Load("*.dll")方法。如果某个接口有多个实现,你还应该在条件绑定的帮助下指定应该使用哪一个。

kernel.Bind<IDealerController>
      .To<SpecialDealerController>()
      .When(x=> SpecialConditionIsMet());

您可以在每个程序集中从NinjectModule继承不同的Module:

public class WarriorModule : NinjectModule
{
    public override void Load() 
    {
        Bind<IWeapon>().To<Sword>();
        Bind<Samurai>().ToSelf().InSingletonScope();
    }
}

然后使用Kernel动态加载AppDomain中所有程序集的所有模块:

kernel.Load(AppDomain.CurrentDomain.GetAssemblies());

所有示例取自Ninject文档