mma*_*007 11 .net c# factory ninject inversion-of-control
我正在使用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...
}
}
Run Code Online (Sandbox Code Playgroud)
这是我在运行时动态创建汽车的对象工厂:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
然后使用ninject工厂扩展"ToFactory"方法绑定我的汽车工厂界面:
public class CarModule : Ninject.Modules.NinjectModule
{
public override void Load()
{
Bind<ICarFactory>().ToFactory();
}
}
Run Code Online (Sandbox Code Playgroud)
我的工厂按预期注入我的服务类,可用于创建汽车对象,但是因为无法将ICar正确地解析为具体类型,因此ninject在这里爆炸.Mercedes或Ferrari由工厂CreateCar()方法返回.
public CarService(string carType, ICarFactory carFactory)
{
var car = carFactory.CreateCar(carType);
}
Run Code Online (Sandbox Code Playgroud)
假设我在这里使用的工厂模式与ninject工厂扩展的工作方式兼容,如何设置ICar的绑定 - >法拉利,ICar - > Mercedes等,以便它们可以在运行时动态解析这种方法?
谢谢!
Aki*_*kim 24
维基上有一个自定义工厂的例子ninject.extension.factory
首先,创建自定义实现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();
}
}
Run Code Online (Sandbox Code Playgroud)
在工厂的CarModule指定UseFirstArgumentAsNameInstanceProvider(自定义实例提供程序)ICarFactory和依赖项的名称
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");
}
}
Run Code Online (Sandbox Code Playgroud)
解决工厂和依赖项
var factory = kernel.Get<ICarFactory>();
var mercedes = factory.CreateCar("Mercedes");
var ferrari = factory.CreateCar("Ferrari");
Run Code Online (Sandbox Code Playgroud)
ps:这是完整的例子