在标准应用程序中注入自定义代码
本文关键字:自定义 代码 注入 标准 应用程序 | 更新日期: 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文档