C# Ninject如何避免多名称绑定的数组注入
查看下面的代码,为了处理接口的单绑定和命名绑定的情况,这里建议使用抽象工厂 这里的挑战是,我需要引入C# Ninject如何避免多名称绑定的数组注入,c#,dependency-injection,ninject,C#,Dependency Injection,Ninject,查看下面的代码,为了处理接口的单绑定和命名绑定的情况,这里建议使用抽象工厂 这里的挑战是,我需要引入IEnumerable bankingOperationList,而不是T bankingOperationList,因为对于命名绑定,它将始终使用抽象工厂注入,Func bankingOperationFunc,但如果我不使用上面建议的IEnumerable,则会导致异常,由于这一点,即使是未命名的单个绑定,我也需要使用如下内容: bankingOperationList.FirstOrDef
IEnumerable bankingOperationList
,而不是T bankingOperationList
,因为对于命名绑定,它将始终使用抽象工厂注入,Func bankingOperationFunc
,但如果我不使用上面建议的IEnumerable
,则会导致异常,由于这一点,即使是未命名的单个绑定,我也需要使用如下内容:
bankingOperationList.FirstOrDefault().draw()
,即使我知道只有一个依赖项。
另一个挑战是,对于一些命名绑定,它在少数情况下有30-40个绑定,当我可以将T bankingooperationlist
默认为null时,这些绑定将被不必要地填充,因为这不是必需的。如果问题需要进一步澄清,请让我知道。下面是工作控制台项目
public interface IBankingOperation
{
void Withdraw();
}
public class BankingOperationOne : IBankingOperation
{
public BankingOperationOne()
{
Console.WriteLine("Testing Constructor :: One :: Empty");
}
public void Withdraw()
{
Console.WriteLine("Money Withdrawl Operation One");
}
}
public class BankingOperationTwo : IBankingOperation
{
public BankingOperationTwo()
{
Console.WriteLine("Testing Constructor :: Two :: Empty");
}
public void Withdraw()
{
Console.WriteLine("Money Withdrawl Operation Two");
}
}
// Ninject Bindings
public class Bindings : NinjectModule
{
public override void Load()
{
Bind<IBankingOperation>().To<BankingOperationOne>()
.Named("A");
Bind<IBankingOperation>().To<BankingOperationTwo>()
.Named("B");
Bind<Func<string,IBankingOperation>>().ToMethod(ctx => name => ctx.Kernel.Get<IBankingOperation>(name));
}
}
public class BankTran<T> where T : IBankingOperation
{
private IEnumerable<T> bankingOperationList = null;
private Func<string,T> bankingOperationFunc;
public BankTran(IEnumerable<T> boList = null,
Func<string,T> boFunc = null)
{
bankingOperationList = boList;
bankingOperationFunc = boFunc;
}
public void DoOperation(string identifier = null)
{
if(bankingOperationFunc != null)
bankingOperationFunc(identifier).Withdraw();
else
bankingOperationList.FirstOrDefault().Withdraw();
Console.WriteLine("Transaction Successful ");
}
}
class Program
{
static void Main(string[] args)
{
var kernel = new StandardKernel();
kernel.Load(Assembly.GetExecutingAssembly()); // Load from Bindings (derived from NinjectModule)
var transaction = kernel.Get<BankTran<IBankingOperation>>();
transaction.DoOperation("A");
}
}
公共接口IBankingOperation
{
无效撤回();
}
公共类银行业务一:IBankingOperation
{
公共银行业务一
{
WriteLine(“测试构造函数::一::空”);
}
公开撤回
{
控制台。WriteLine(“取款操作一”);
}
}
公共类银行业务二:IBankingOperation
{
公共银行业务(二)
{
WriteLine(“测试构造函数::两个::空”);
}
公开撤回
{
控制台。WriteLine(“取款操作二”);
}
}
//Ninject绑定
公共类绑定:NinjectModule
{
公共覆盖无效负载()
{
将()绑定到()上
.命名为(“A”);
将()绑定到()上
.命名为(“B”);
Bind().ToMethod(ctx=>name=>ctx.Kernel.Get(name));
}
}
公共类BankTran,其中T:IBankingOperation
{
private IEnumerable bankingOperationList=null;
私人职能银行业务职能;
public BankTran(IEnumerable boList=null,
Func boFunc=null)
{
bankingOperationList=boList;
bankingooperationfunc=boFunc;
}
公共void DoOperation(字符串标识符=null)
{
if(bankingooperationfunc!=null)
bankingOperationFunc(标识符).draw();
其他的
bankingOperationList.FirstOrDefault().Draw();
Console.WriteLine(“交易成功”);
}
}
班级计划
{
静态void Main(字符串[]参数)
{
var kernel=新的标准内核();
kernel.Load(Assembly.getExecutionGassembly());//从绑定加载(从NinjectModule派生)
var transaction=kernel.Get();
交易操作(“A”);
}
}
根据jbl的回复编辑1
public interface IBankingOperation<T>
{
void Withdraw();
}
public class BankingOperationOne : IBankingOperation<TestOne>
{
public BankingOperationOne()
{
Console.WriteLine("Testing Constructor :: One :: Empty");
}
public void Withdraw()
{
Console.WriteLine("Money Withdrawl Operation One");
}
}
public class BankingOperationTwo : IBankingOperation<TestTwo>
{
public BankingOperationTwo()
{
Console.WriteLine("Testing Constructor :: Two :: Empty");
}
public void Withdraw()
{
Console.WriteLine("Money Withdrawl Operation Two");
}
}
public class TestOne { }
public class TestTwo { }
// Ninject Bindings
public class Bindings : NinjectModule
{
public override void Load()
{
Bind<IBankingOperation<TestOne>>().To<BankingOperationOne>().Named("A");
Bind<IBankingOperation<TestOne>>().To<BankingOperationOne>().Named("B");
Bind<IBankingOperation<TestOne>>().To<BankingOperationOne>().WhenInjectedInto(typeof(BankTran<TestOne>));
Bind<Func<string, IBankingOperation<TestOne>>>().ToMethod(ctx => name => ctx.Kernel.Get<IBankingOperation<TestOne>>(name));
Bind<IBankingOperation<TestTwo>>().To<BankingOperationTwo>();
}
}
public class BankTran<T> where T : class
{
private IBankingOperation<T> bankingOperation;
private Func<string, IBankingOperation<T>> bankingOperationFunc;
public BankTran(IBankingOperation<T> bo = null,
Func<string, IBankingOperation<T>> boFunc = null)
{
bankingOperation = bo;
bankingOperationFunc = boFunc;
}
public void DoOperation(string identifier = null)
{
if (bankingOperationFunc != null && identifier != null)
bankingOperationFunc(identifier).Withdraw();
else if (bankingOperation != null)
bankingOperation.Withdraw();
Console.WriteLine("Transaction Successful ");
}
}
class Program
{
static void Main(string[] args)
{
var kernel = new StandardKernel(new NinjectSettings { AllowNullInjection = true});
kernel.Load(Assembly.GetExecutingAssembly()); // Load from Bindings (derived from NinjectModule)
var transaction = kernel.Get<BankTran<TestOne>>("A"); // Not Working
// var transaction = kernel.Get<BankTran<TestOne>>(); // Working
transaction.DoOperation();
}
}
公共接口IBankingOperation
{
无效撤回();
}
公共类银行业务一:IBankingOperation
{
公共银行业务一
{
WriteLine(“测试构造函数::一::空”);
}
公开撤回
{
控制台。WriteLine(“取款操作一”);
}
}
公共类银行业务二:IBankingOperation
{
公共银行业务(二)
{
WriteLine(“测试构造函数::两个::空”);
}
公开撤回
{
控制台。WriteLine(“取款操作二”);
}
}
公共类TestOne{}
公共类TestTwo{}
//Ninject绑定
公共类绑定:NinjectModule
{
公共覆盖无效负载()
{
绑定()到名为(“A”);
绑定()到()名为(“B”);
Bind().To()。当对象为(typeof(BankTran));
Bind().ToMethod(ctx=>name=>ctx.Kernel.Get(name));
绑定()到();
}
}
公共类BankTran,其中T:class
{
私人银行业务银行业务;
私人职能银行业务职能;
public BankTran(IBankingOperation bo=null,
Func boFunc=null)
{
bankingOperation=bo;
bankingooperationfunc=boFunc;
}
公共void DoOperation(字符串标识符=null)
{
if(bankingooperationfunc!=null&&identifier!=null)
bankingOperationFunc(标识符).draw();
else if(bankingooperation!=null)
bankingooperation.draw();
Console.WriteLine(“交易成功”);
}
}
班级计划
{
静态void Main(字符串[]参数)
{
var-kernel=new-StandardKernel(new-NinjectSettings{AllowNullInjection=true});
kernel.Load(Assembly.getExecutionGassembly());//从绑定加载(从NinjectModule派生)
var transaction=kernel.Get(“A”);//不工作
//var transaction=kernel.Get();//正在工作
transaction.DoOperation();
}
}
假设BankingOperationOne
是您的默认行为,
在加载方法中添加以下行应允许将BankTran构造函数中的IEnumerable
替换为T
:
Bind<IBankingOperation>().To<BankingOperationOne>().WhenInjectedInto(typeof(BankTran<>));
编辑:
您应该使用nuget包。
使用这个包,下面的代码似乎满足了您的需求
public interface IBankingOperation<T>
{
void Withdraw();
}
public interface IBankingOperationFactory<T>
{
IBankingOperation<T> GetBankingOperation(string name);
}
public class BankingOperationOne : IBankingOperation<TestOne>
{
public BankingOperationOne()
{
Console.WriteLine("Testing Constructor :: One :: Empty");
}
public void Withdraw()
{
Console.WriteLine("Money Withdrawl Operation One");
}
}
public class BankingOperationTwo : IBankingOperation<TestTwo>
{
public BankingOperationTwo()
{
Console.WriteLine("Testing Constructor :: Two :: Empty");
}
public void Withdraw()
{
Console.WriteLine("Money Withdrawl Operation Two");
}
}
public class TestOne { }
public class TestTwo { }
// Ninject Bindings
public class Bindings : NinjectModule
{
public override void Load()
{
Bind<IBankingOperation<TestOne>>().To<BankingOperationOne>().Named("A");
Bind<IBankingOperation<TestOne>>().To<BankingOperationOne>().Named("B");
Bind<IBankingOperation<TestOne>>().To<BankingOperationOne>().WhenInjectedInto(typeof(BankTran<TestOne>));
Bind<IBankingOperationFactory<IBankingOperation<TestOne>>>().ToFactory();
Bind<IBankingOperation<TestTwo>>().To<BankingOperationTwo>();
}
}
public class BankTran<T> where T : class
{
private IBankingOperation<T> bankingOperation;
private IBankingOperationFactory<T> _bankingOperationFactory;
public BankTran(IBankingOperation<T> bo = null,
IBankingOperationFactory<T> bankingOperationFactory = null)
{
bankingOperation = bo;
_bankingOperationFactory = bankingOperationFactory;
}
public void DoOperation(string identifier = null)
{
if (_bankingOperationFactory != null && identifier != null)
_bankingOperationFactory.GetBankingOperation(identifier).Withdraw();
else if (bankingOperation != null)
bankingOperation.Withdraw();
Console.WriteLine("Transaction Successful ");
}
}
class Program
{
static void Main(string[] args)
{
var kernel = new StandardKernel(new NinjectSettings { AllowNullInjection = true });
kernel.Load(Assembly.GetExecutingAssembly()); // Load from Bindings (derived from NinjectModule)
var transaction = kernel.Get<BankTran<TestOne>>();
transaction.DoOperation();
transaction.DoOperation("A");
transaction.DoOperation("B");
}
}
公共接口IBankingOperation
{
无效撤回();
}
公共接口IBankingOperationFactory
{
IBankingOperation GetBankingOperation(字符串名称);
}
公共类银行业务一:IBankingOperation
{
公共银行业务一
{
WriteLine(“测试构造函数::一::空”);
}
公开撤回
{
控制台。WriteLine(“取款操作一”);
}
}
公共类银行业务二:IBankingOperation
{
公共银行业务(二)
{
WriteLine(“测试构造函数::两个::空”);
}
公开撤回
{
控制台。WriteLine(“周一
public void DoOperation(string identifier = "__DefaultBehaviour")
{
if (bankingOperationFunc != null)
bankingOperationFunc(identifier).Withdraw();
Console.WriteLine("Transaction Successful ");
}
public interface IBankingOperation<T>
{
void Withdraw();
}
public interface IBankingOperationFactory<T>
{
IBankingOperation<T> GetBankingOperation(string name);
}
public class BankingOperationOne : IBankingOperation<TestOne>
{
public BankingOperationOne()
{
Console.WriteLine("Testing Constructor :: One :: Empty");
}
public void Withdraw()
{
Console.WriteLine("Money Withdrawl Operation One");
}
}
public class BankingOperationTwo : IBankingOperation<TestTwo>
{
public BankingOperationTwo()
{
Console.WriteLine("Testing Constructor :: Two :: Empty");
}
public void Withdraw()
{
Console.WriteLine("Money Withdrawl Operation Two");
}
}
public class TestOne { }
public class TestTwo { }
// Ninject Bindings
public class Bindings : NinjectModule
{
public override void Load()
{
Bind<IBankingOperation<TestOne>>().To<BankingOperationOne>().Named("A");
Bind<IBankingOperation<TestOne>>().To<BankingOperationOne>().Named("B");
Bind<IBankingOperation<TestOne>>().To<BankingOperationOne>().WhenInjectedInto(typeof(BankTran<TestOne>));
Bind<IBankingOperationFactory<IBankingOperation<TestOne>>>().ToFactory();
Bind<IBankingOperation<TestTwo>>().To<BankingOperationTwo>();
}
}
public class BankTran<T> where T : class
{
private IBankingOperation<T> bankingOperation;
private IBankingOperationFactory<T> _bankingOperationFactory;
public BankTran(IBankingOperation<T> bo = null,
IBankingOperationFactory<T> bankingOperationFactory = null)
{
bankingOperation = bo;
_bankingOperationFactory = bankingOperationFactory;
}
public void DoOperation(string identifier = null)
{
if (_bankingOperationFactory != null && identifier != null)
_bankingOperationFactory.GetBankingOperation(identifier).Withdraw();
else if (bankingOperation != null)
bankingOperation.Withdraw();
Console.WriteLine("Transaction Successful ");
}
}
class Program
{
static void Main(string[] args)
{
var kernel = new StandardKernel(new NinjectSettings { AllowNullInjection = true });
kernel.Load(Assembly.GetExecutingAssembly()); // Load from Bindings (derived from NinjectModule)
var transaction = kernel.Get<BankTran<TestOne>>();
transaction.DoOperation();
transaction.DoOperation("A");
transaction.DoOperation("B");
}
}