我刚刚开始学习IoC和依赖注入。 我计划做一个MonoTouch项目,想使用TinyIoC,但我想先测试一下。 我正在创建一个虚拟信用卡处理控制台应用程序,由于我的界面有多个实现,因此我在如何配置 TinyIoC 方面遇到问题。这是我的测试应用程序。
接口:
public interface IPaymentProcessor
{
void ProcessPayment(string cardNumber);
}
接口的两个实现:
签证支付处理器
public class VisaPaymentProcessor : IPaymentProcessor
{
public void ProcessPayment(string cardNumber)
{
if (cardNumber.Length != 13 && cardNumber.Length != 16)
{
new ArgumentException("Card Number isn't the correct length");
}
// some code for processing payment
}
}
美国运通支付处理器
public class AmexPaymentProcessor : IPaymentProcessor
{
public void ProcessPayment(string cardNumber)
{
if (cardNumber.Length != 15)
{
new ArgumentException("Card Number isn't the correct length");
}
// some code for processing the payment
}
}
简单的东西。 现在我有一个接受接口作为构造函数中的参数的类。
信用卡处理器
public class CreditCardProcessor
{
public IPaymentProcessor PaymentProcessor { get; set; }
public CreditCardProcessor(IPaymentProcessor processor)
{
this.PaymentProcessor = processor;
}
public void ProcessPayment(string creditCardNumber)
{
this.PaymentProcessor.ProcessPayment(creditCardNumber);
}
}
我的控制台应用程序看起来像这样。
class Program
{
static void Main(string[] args)
{
TinyIoCContainer.Current.AutoRegister();
var creditCardProcessor = TinyIoCContainer.Current.Resolve<CreditCardProcessor>();
creditCardProcessor.ProcessPayment("1234567890123456"); // 16 digits
}
}
所以我试图弄清楚如何告诉Resolve
将接口的哪个实现传递给构造函数。 如果我运行此代码,我将始终使用 VisaPaymentProcessor
实现。
那么如何使 TinyIoC 将AmexPaymentProcessor
实现传递给构造函数而不是VisaPaymentProcessor
(这似乎是默认值(?
我自己没有使用过TinyIoC,但我怀疑你想要:
TinyIoCContainer.Current.Register(typeof(IPaymentProcessor),
typeof(AmexPaymentProcessor));
(如果您想使用美国运通卡。
还有其他各种可用的Register
重载,包括一个使用名称的重载,这在解决时可能很有用。这真的取决于你想要实现什么,这从这个问题上看不是很清楚。
我不太确定你在这里要实现什么,但是如果你有一个接口的多个实现,并且你想要一个特定的实现,那么你需要用一个名称注册每个,或者使用 RegisterMultiple,它使用类型名称作为名称,然后使用该名称进行解析并将其与 NamedParameterOverload 一起使用来指定您想要的那个。
这听起来更像是你可能想要某种 ProcessorFactory,或者某种外观,它依赖于 IEnumerable,并根据传入的数量提供/充当正确实现的外观。
在 Global.asax 或应用程序条目中类似这样的东西(针对您的示例进行了修改(
const string nameTrim = "paymentprocessor";
var type = typeof(IPaymentProcessor);
AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(x => type.IsAssignableFrom(x) && x.IsClass).ToList()
.ForEach(t =>
{
var name = t.Name.ToLower();
if (name.EndsWith(nameTrim))
name = name.Substring(0, name.Length - nameTrim.Length);
TinyIoCContainer.Current.Register(type, t, name);
});
它找到 IPaymentProcessor 的所有实现,并使用类名注册它们(-PaymentProcessor,如果类名以 PaymentProcessor 结尾(
然后我可以解决例如"AmexPaymentProcessor"
IPaymentProcessor handler;
if (TinyIoCContainer.Current.TryResolve("amex", out handler))
{
response = handler.ProcessPayment(cardNumber);
}