介绍:
我正在使用Ninject Factory Extension将简单的对象工厂注入到我的服务类中.
这是我的界面和两个实现它的类:
public interface ICar { void Drive(); void Stop(); } public class Mercedes : ICar { public void Drive() { Do mercedes drive stuff... } public void Stop() { Do mercedes stop stuff... } } public class Ferrari : ICar { public void Drive() { Do ferrari drive stuff... } public void Stop() { Do ferrari stop stuff... } }
这是我的对象工厂在运行时动态创建一辆汽车:
public interface ICarFactory { ICar CreateCar(string carType); } public class CarFactory : ICarFactory { public ICar CreateCar(string carType) { ICar car; switch (type) { case "mercedes": car = new Mercedes(); break; case "ferrari": car = new Ferrari(); break; } return car; } }
然后使用ninject工厂扩展“ToFactory”方法绑定我的车厂界面:
public class CarModule : Ninject.Modules.NinjectModule { public override void Load() { Bind<ICarFactory>().ToFactory(); } }
问题:
我的工厂按预期注入我的服务类,可以用来创建
汽车对象,但是因为它不能正确地解决ICAR,所以Ninject在这里爆炸
到具体类型ie.梅赛德斯或法拉利由工厂CreateCar()方法返回.
public CarService(string carType,ICarFactory carFactory) { var car = carFactory.CreateCar(carType); }
题:
假设我在这里使用的工厂模式与ninject工厂扩展是如何工作兼容的,我如何设置ICar的绑定 – >法拉利,ICar – >梅赛德斯等,以便在运行时可以通过这种方式动态解决?
谢谢!
解决方法
有一个在
ninject.extension.factory
wiki定制工厂的例子
首先,创建StandardInstanceProvider的自定义实现来覆盖默认工厂行为
public class UseFirstArgumentAsNameInstanceProvider : StandardInstanceProvider { protected override string GetName(System.Reflection.MethodInfo methodInfo,object[] arguments) { return (string)arguments[0]; } protected override ConstructorArgument[] GetConstructorArguments(MethodInfo methodInfo,object[] arguments) { return base.GetConstructorArguments(methodInfo,arguments).Skip(1).ToArray(); } }
在CarModule中为ICarFactory工厂指定UseFirstArgumentAsNameInstanceProvider(自定义实例提供程序),并为依赖项指定名称
public class CarModule : NinjectModule { public override void Load() { Bind<ICarFactory>() .ToFactory(() => new UseFirstArgumentAsNameInstanceProvider()); Bind<ICar>() .To<Mercedes>() .Named("Mercedes"); Bind<ICar>() .To<Ferrari>() .Named("Ferrari"); } }
解决工厂和依赖关系
var factory = kernel.Get<ICarFactory>(); var mercedes = factory.CreateCar("Mercedes"); var ferrari = factory.CreateCar("Ferrari");
ps:这是full example