将依赖关系传递给Factory

时间:2014-03-10 16:40:33

标签: c# dependency-injection inversion-of-control factory-pattern

我们正在使用工厂来创建订阅者的实例。每个订户都可以拥有自己的依赖项。

每个订阅者都将使用构造函数注入。

我应该通过Subscriber Factory将依赖项传递给订阅者吗?每次在任何订户中添加新依赖项都会更改订阅服务器工厂吗?

public interface IMessageSubscriber
{
    bool Process(string message)
}

public class MessageSubscriber1 : IMessageSubscriber
{
    public bool Process(string message)
    {
        //Some custom logic 
    }
}

public class MessageSubscriber2 : IMessageSubscriber
{
    public bool Process(string message)
    {
        //Some custom logic 
    }
}

public class MessageSubscriberFactory
{

    //SubscriberType is enum
    public IMessageSubscriber Get(SubscriberType type)
    {
            if(type == 1)
            {
                return new MessageSubscriber1();
            }
            else if(type == 2)
            {
                return new MessageSubscriber2();            
            }
    }
}

//Main class
public class Process
{
    public static void Main(string[] args)
    {
        MessageSubscriberFactory fac = new MessageSubscriberFactory();
        foreach SubscriberType
        {
            string  = "Message";
            IMessageSubscriber subscriber = fac.Get(type);
            subscriber.Process(message)
        }
    }
}

1 个答案:

答案 0 :(得分:2)

一种方法是使用带有DI / IOC容器的命名注册。这将涉及以服务定位器的方式使用容器(有些人反对),但我认为在这种情况下它可能有意义。下面的示例非常简洁,但它确实为您提供了一种方法来处理具有不同依赖关系的订阅者,而无需将其传递到工厂。我在这里使用了Unity,你想要包装容器引用而不是直接引用,但这可以解决问题。

public interface ILowerCaseWriter
{
    void Write(string message);
}
public class LowerCaseWriter : ILowerCaseWriter
{
    public void Write(string message)
    {
        Console.WriteLine(message.ToLower());
    }
}

public interface IUpperCaseWriter
{
    void Write(string message, int number);
}
public class UpperCaseWriter : IUpperCaseWriter
{
    public void Write(string message, int number)
    {
        Console.WriteLine("{0}:{1}", number, message.ToUpper());
    }
}

public interface ISubscriber
{
    void Write();
}
public class Subscriber1 : ISubscriber
{
    private ILowerCaseWriter _writer;
    public Subscriber1(ILowerCaseWriter writer)
    {
        _writer = writer;
    }
    public void Write()
    {
        _writer.Write("Using subscriber 1");
    }
}
public class Subscriber2 : ISubscriber
{
    private IUpperCaseWriter _writer;
    public Subscriber2(IUpperCaseWriter writer)
    {
        _writer = writer;
    }
    public void Write()
    {
        _writer.Write("Using subscriber 2", 2);
    }
}

public class SubscriberFactory
{
    private UnityContainer _container;
    public SubscriberFactory()
    {
        _container = new UnityContainer();
        _container.RegisterType<ILowerCaseWriter, LowerCaseWriter>();
        _container.RegisterType<IUpperCaseWriter, UpperCaseWriter>();
        _container.RegisterType<ISubscriber, Subscriber1>("Subscriber1");
        _container.RegisterType<ISubscriber, Subscriber2>("Subscriber2");
    }

    public ISubscriber GetSubscriber(int type)
    {
        switch (type)
        {
            case 1:
                return _container.Resolve<ISubscriber>("Subscriber1");
            case 2:
                return _container.Resolve<ISubscriber>("Subscriber2");
            default:
                throw new Exception();
        }
    }
}

class Program
{
    private static void Main(string[] args)
    {
        var factory = new SubscriberFactory();
        var subscriber = factory.GetSubscriber(1);
        subscriber.Write();
        Console.ReadLine();
    }
}