审查下面的代码,在那里照顾的情况下与接口单,并命名为结合数组注射,使用了抽象工厂这里Ninject如何避免多个名称绑定
Parameterized Factories Using Ninject
建议这里面临的挑战是,我需要引入IEnumerable<T> bankingOperationList
而不是T bankingOperationList
,因为对于命名绑定,它将始终使用抽象工厂注入Func<string,T> bankingOperationFunc
,但如果我不使用上面建议的IEnumerable<T>
,则会导致异常,因为这会导致偶数非命名单绑定,我需要使用类似: bankingOperationList.FirstOrDefault().Withdraw()
,即使我知道只会有一个依赖。 另一个挑战是,对于某些命名的绑定,在少数情况下它有30-40个绑定,当我可以将T bankingOperationList
默认为空时,它将被不必要地填充,因为它不是必需的。请让我知道,如果这个问题需要进一步澄清。下方的工作控制台项目。
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");
}
}
编辑1,由JBL
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();
}
}
注入'Func'是完成工作的一种方法。使用[策略模式](https://stackoverflow.com/a/31971691/)是另一个。这将是清单手头上的“清单”的更清晰的解决方案。也就是说,你不清楚你想要解决什么问题 - 它是从列表中获得“默认”操作吗? – NightOwl888
@ NightOwl888问题是多个相同类型的绑定将由'Func'处理,另一个'IEnumerable '不被使用,它只需要一对一/唯一/未命名的绑定,但仍然需要一个集合,否则对于命名绑定导致异常,它们被不必要地填充。请运行代码并尝试'T bankingOperation'而不是'Banknoperable bankingOperationList'在'BankTran '中,您将会得到我正在谈论的问题 –
@ NightOwl888我回顾了您提供的解决方案,它避免了需要'Func ','ICarFactory []'本身找到了正确的对象,但这样我就能够使当前的解决方案工作得很好,我只是想避免命名绑定需求来填充集合,但Ninject仍然存在线索少在这种情况下,并希望收集填写 –