首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >TinyIoC -接口的多个实现

TinyIoC -接口的多个实现
EN

Stack Overflow用户
提问于 2012-05-02 20:50:40
回答 3查看 4.4K关注 0票数 8

我刚刚开始了解IoC和依赖项注入。我计划做一个MonoTouch项目,并想使用TinyIoC,但我想先测试一下。我正在创建一个虚拟的信用卡处理控制台应用程序,而且由于我有多个接口实现,所以我在如何配置TinyIoC方面遇到了困难。这是我的测试应用。

接口

代码语言:javascript
复制
public interface IPaymentProcessor
{
    void ProcessPayment(string cardNumber);
}

接口的两个实现:

VisaPaymentProcessor

代码语言:javascript
复制
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
    }
}

AmexPaymentProcessor

代码语言:javascript
复制
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
    }
}

简单的东西。现在我有了一个类,它将接口作为构造函数中的一个参数.

CreditCardProcessor

代码语言:javascript
复制
public class CreditCardProcessor
{
    public IPaymentProcessor PaymentProcessor { get; set; }

    public CreditCardProcessor(IPaymentProcessor processor)
    {
        this.PaymentProcessor = processor;
    }

    public void ProcessPayment(string creditCardNumber)
    {
        this.PaymentProcessor.ProcessPayment(creditCardNumber);
    }
}

我的控制台应用程序是这样的..。

代码语言:javascript
复制
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(这似乎是默认的)?

EN

回答 3

Stack Overflow用户

发布于 2012-05-02 21:00:55

我自己也没用过TinyIoC,但我怀疑你想要:

代码语言:javascript
复制
TinyIoCContainer.Current.Register(typeof(IPaymentProcessor),
                                  typeof(AmexPaymentProcessor));

(如果你想使用美国运通。)

还有其他各种可用的Register重载,包括一个使用名称的重载,这在解析时可能很有用。这真的取决于你想要达到的目标,从问题上看,这并不是很清楚。

票数 7
EN

Stack Overflow用户

发布于 2012-05-02 21:09:19

我不太清楚您在这里试图实现什么,但是如果您有多个接口实现,并且您想要一个特定的接口,那么您需要用一个名称注册每个接口,或者使用RegisterMultiple,它使用名称的类型名称,然后使用该名称进行解析,并与NamedParameterOverloads一起使用该名称来指定您想要的接口。

听起来更像是您可能想要某种类型的ProcessorFactory,或者某种外观,它需要依赖于IEnumerable,并根据传入的数量提供/充当正确实现的外观。

票数 2
EN

Stack Overflow用户

发布于 2014-03-07 23:54:39

类似于Global.asax或应用程序条目中的内容(针对您的示例进行修改)

代码语言:javascript
复制
        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“

代码语言:javascript
复制
        IPaymentProcessor handler;
        if (TinyIoCContainer.Current.TryResolve("amex", out handler))
        {
            response = handler.ProcessPayment(cardNumber);
        }
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10421505

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档