问题
We have a standard application in our company. Now I want to inject some custom assemblies in the application.
Normally if you have a ninject kernel or unity container, you can get the implementation like below:
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 interface
public interface IDealerController
{
Dealer GetDealerDetails(int dealerId);
}
Implementation of the dealer controller:
public class DealerController : IDealerController
{
public Dealer GetDealerDetails(int dealerId)
{
throw new NotImplementedException("This is a custom error thrown from the controller implementation");
}
}
Now the thing is that I don't want that the standard application knows about the custom assemblies. The dealerservice is a workflow activity so that is found dynamically by workflow foundation. The problem is that the injected DealerController
is empty...
How can I inject the implementation of the IDealerController
in my standardapplication without the line kernel.Get<IDealerController>()
.
If you use Ninject with the ninject MVC 3 nuget package, the implementation is injected in the constructor of the mvc controller without calling the kernel.Get<IDealerController>()
.
Edit: Added the module with as assembly name Ninject.Extensions.Controllers.Module so the Module is found by naming convention. This is described in the Ninject documentation. This works in my MVC application.
public class ControllersModule : NinjectModule
{
public override void Load()
{
this.Bind<IDealerController>().To<DealerController>();
}
}
回答1:
If you want to inject the IDealerController
implementation into DealerService
, you will also have to let Ninject to manage the instantiation of the DealerService
.
IKernel kernel = new StandardKernel();
kernel.Bind<IDealerController>.To<DefaultDealerController>(); //.InSingletonScope();
kernel.Bind<DealerService>().ToSelf(); //.InSingletonScope();
DealerService myServ = kernel.Get<DealerService>();
To dynamically load Ninject configuration you can use modules approach and kernel.Load("*.dll")
method. If you will have multiple implementations of some interface, you should also specify which one should be used with the help of the conditional binding.
kernel.Bind<IDealerController>
.To<SpecialDealerController>()
.When(x=> SpecialConditionIsMet());
回答2:
You can have different Module
inheriting from NinjectModule
in each assembly:
public class WarriorModule : NinjectModule
{
public override void Load()
{
Bind<IWeapon>().To<Sword>();
Bind<Samurai>().ToSelf().InSingletonScope();
}
}
Then use the Kernel
to dynamically load all modules from all assemblies in AppDomain
:
kernel.Load(AppDomain.CurrentDomain.GetAssemblies());
All examples are taken from Ninject documentation.
来源:https://stackoverflow.com/questions/15482476/inject-custom-code-in-standard-application