phi*_*hil 3 c# factory ninject decorator
尝试使用ninject将泛型参数传递给装饰器链时遇到了问题.也许最好用代码解释一下:
public interface IConnector
{
void Connect();
}
public class CoreConnector : IConnector
{
public void Connect()
{
Console.WriteLine("core connector");
}
}
public class LoggingConnector : IConnector
{
private readonly IConnector conn;
private string id;
public LoggingConnector(IConnector conn, string id)
{
this.conn = conn;
this.id = id;
}
public void Connect()
{
Console.WriteLine("logging conn id : {0}",id);
conn.Connect();
}
}
public class AuditingConnector : IConnector
{
private readonly IConnector conn;
private string id;
public AuditingConnector(IConnector conn, string id)
{
this.conn = conn;
this.id = id;
}
public void Connect()
{
Console.WriteLine("auditing conn id : {0}", id);
conn.Connect();
}
}
public interface IConnectorFactory
{
IConnector CreateConnector(string id);
}
class Tests
{
public static void Test0()
{
var kernel = new StandardKernel();
kernel.Bind<IConnector>().To<CoreConnector>().WhenInjectedInto<LoggingConnector>().InSingletonScope();
kernel.Bind<IConnector>().To<LoggingConnector>();
kernel.Bind<IConnectorFactory>().ToFactory();
var factory = kernel.Get<IConnectorFactory>();
var connector = factory.CreateConnector("12345");
connector.Connect();
}
public static void Test1()
{
var kernel = new StandardKernel();
kernel.Bind<IConnector>().To<CoreConnector>().WhenInjectedInto<AuditingConnector>().InSingletonScope();
kernel.Bind<IConnector>().To<AuditingConnector>().WhenInjectedInto<LoggingConnector>();
kernel.Bind<IConnector>().To<LoggingConnector>();
kernel.Bind<IConnectorFactory>().ToFactory();
var factory = kernel.Get<IConnectorFactory>();
var connector = factory.CreateConnector("12345");
connector.Connect();
}
}
Run Code Online (Sandbox Code Playgroud)
显然,Test0通过,Test1失败.如何将这些装饰器与工厂联系起来?
您可以使用激活上下文来查找父构造函数中使用的参数.像这样:
kernel.Bind<IConnector>()
.To<AuditingConnector>()
.WhenInjectedInto<LoggingConnector>()
.WithConstructorArgument("id",
ctx => ctx.Request.ParentContext.Parameters
.Single(x => x.Name == "id")
.GetValue(ctx, null));
Run Code Online (Sandbox Code Playgroud)
或者,您可以设置自定义实例提供程序以与工厂一起使用,该工具将参数传递到链中:
kernel.Bind<IConnectorFactory>().ToFactory(() => new CustomInstanceProvider());
Run Code Online (Sandbox Code Playgroud)
其中CustomInstanceProvider如下:
public class CustomInstanceProvider : StandardInstanceProvider
{
protected override ConstructorArgument[] GetConstructorArguments(MethodInfo methodInfo, object[] arguments)
{
var parameters = methodInfo.GetParameters();
var constructorArguments = new ConstructorArgument[parameters.Length];
for (int i = 0; i < parameters.Length; i++)
{
constructorArguments[i] = new ConstructorArgument(parameters[i].Name, arguments[i], true);
}
return constructorArguments;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
599 次 |
| 最近记录: |