WCF依赖注入和抽象工厂

tar*_*afe 19 wcf dependency-injection factory-pattern

我有这个wcf方法

Profile GetProfileInfo(string profileType, string profileName)
Run Code Online (Sandbox Code Playgroud)

和业务规则:

如果profileType是从数据库中读取的"A".

如果profileType是从"xml"文件中读取的"B".

问题是:如何使用依赖注入容器实现它?

Mar*_*ann 23

我们首先假设你有一个类似这样的IProfileRepository:

public interface IProfileRepository
{
     Profile GetProfile(string profileName);
}
Run Code Online (Sandbox Code Playgroud)

以及两个实现:DatabaseProfileRepositoryXmlProfileRepository.问题是您希望根据profileType的值选择正确的值.

你可以通过介绍这个抽象工厂来做到这一点:

public interface IProfileRepositoryFactory
{
    IProfileRepository Create(string profileType);
}
Run Code Online (Sandbox Code Playgroud)

假设已将IProfileRepositoryFactory注入到服务实现中,您现在可以像这样实现GetProfileInfo方法:

public Profile GetProfileInfo(string profileType, string profileName)
{
    return this.factory.Create(profileType).GetProfile(profileName);
}
Run Code Online (Sandbox Code Playgroud)

IProfileRepositoryFactory的具体实现可能如下所示:

public class ProfileRepositoryFactory : IProfileRepositoryFactory
{
    private readonly IProfileRepository aRepository;
    private readonly IProfileRepository bRepository;

    public ProfileRepositoryFactory(IProfileRepository aRepository,
        IProfileRepository bRepository)
    {
        if(aRepository == null)
        {
            throw new ArgumentNullException("aRepository");
        }
        if(bRepository == null)
        {
            throw new ArgumentNullException("bRepository");
        }

        this.aRepository = aRepository;
        this.bRepository = bRepository;
    }

    public IProfileRepository Create(string profileType)
    {
        if(profileType == "A")
        {
            return this.aRepository;
        }
        if(profileType == "B")
        {
            return this.bRepository;
        }

        // and so on...
    }
}
Run Code Online (Sandbox Code Playgroud)

现在您只需要选择DI容器就可以为您完成所有连接......

  • 是的,那里没有分歧,但我只是选择OP给出的API :) (3认同)

小智 6

Mark 的回答很好,但是给出的解决方案不是抽象工厂,而是标准工厂模式的实现。请检查 Marks 类如何适合标准工厂模式 UML 图表。单击此处查看上述应用于工厂模式 UML 的类

由于在工厂模式中,工厂知道具体的类,我们可以使代码ProfileRepositoryFactory更简单,如下所示。将不同的存储库注入工厂的问题在于,每次添加新的具体类型时,都会有更多的代码更改。使用以下代码,您只需更新开关以包含新的具体类


    public class ProfileRepositoryFactory : IProfileRepositoryFactory
    {
        public IProfileRepository Create(string profileType)
        {
            switch(profileType)
            {
                case "A":
                    return new DatabaseProfileRepository(); 

                case  "B":
                    return new XmlProfileRepository();
            }
        }
    }

抽象工厂是更高级的模式,用于创建相关或依赖对象的系列,而无需指定它们的具体类。此处提供的 UML 类图很好地解释了它。