1

我正在使用由 Windsor Castle DI 容器提供的 Typed Factory。我对 DI 容器很陌生,所以在对我的解决方案进行了一些指导之后。

这是我的实现:

*更新注册和数据库调用

public interface IAgent {    }
public class Agent : IAgent     {    }

public interface IAgentFactory     
{
    IAgent Create();
    IAgent Create(int agentId);
    IAgent Create(AgentDTO agentDTO);
}

class AgentFactory : IAgentFactory     
{        
    public IAgent Create()         
    {            
        return InitNewEntity(new Agent());
    }
    public IAgent Create(int agentId, IDBContext dbContext) //Not happy with this, as it's a dependency that isn't factored out :(    
    {
        return dbContext.GetAgent(agentId);
    }
    public IAgent Create(AgentDTO agentDTO)
    {
         Agent agent = InitNewEntity(new Agent());
         agent.ParseDTO(agentDTO);
         return agent;
    }
    private IAgent InitNewEntity(IAgent agent)
    {
         agent.Username = "";        /// + other fields to initialise
         agent.DOB = DateTime.Now;   /// etc.
         return agent;
    }

...

Container.AddFacility<TypedFactoryFacility>()
            .Register( Component.For<IAgentFactory>()
                                .ImplementedBy<AgentFactory>());

我正在使用以下调用来获取一些实体

IAgentFactory agentFactory = ViewModel.Container.Resolve<IAgentFactory>();

IAgent agent = agentFactory.Create();  //Creates new Agent entity
agent = agentFactory.Create(66, dbContext); //Looks up entity in database, don't like passing in a db context, another dependency
agent = agentFactory.Create(agentDTO);      //Creates Agent entity from DTO object

我对此有几个担忧。

关于创建新代理有 3 种可能的情况,

1:从头开始创建一个新代理

2:使用现有的 DTO(数据传输对象)创建代理

3:创建一个调用数据库的代理。

我决定将所有这些功能放入工厂,因为它似乎符合要求,但是,我不完全确定这是否是正确或最佳的实现方式。

问题是,是否可以在 DI 容器的 Register 语句中利用所有 3 个 Create 场景并完全省略具体的工厂实现,这样我就不再有 AgentFactory 类,而只有 IAgentFactory 接口。

我对此实现的另一个问题是,是否可以进行调用,这样如果我请求代理实体,Windsor 将首先调用工厂并返回从工厂创建的实体,而不是在没有引用的情况下创建实体工厂。IE。

IAgent agent = Container.Resolve<IAgent>(66);

使用调用堆栈:

Container -> AgentFactory -> Create(66) -> 从工厂返回代理。

哪个 Windsor 会拦截并自动使用工厂创建实例。但是,我尝试了这个,它没有使用工厂来创建它,它只是继续创建代理而不引用工厂。

我确实有这个,但它没有调用我定义的工厂方法。

Container.AddFacility<TypedFactoryFacility>()
            .Register(Component.For<IAgentFactory>().AsFactory(),
                      Component.For<IAgent>().ImplementedBy<Agent>());

感谢您的建议,谢谢。

4

1 回答 1

2

类型化工厂旨在创建“行为”实例,而不是“数据”实例。

您没有将“模型”组件注册到容器中,但可以使用模型工作。换句话说,您将除模型之外的所有内容都注册到容器中。

您的 AgentFactory 必须注册到容器中,但这不是“类型化工厂”。您可以将 TF 用于“后期依赖”目的。

我更喜欢与我的设计更加解耦,也更倾向于“单一责任”。AgentFactory 不会在工厂中隐藏存储库(根据您的从数据库创建):我将通过数据读取器作为创建参数。

于 2012-07-02T10:58:24.327 回答