1

Я использую Типичный завод, поставленный Виндзорским замком DI контейнера. Я совершенно новичок в контейнерах DI, так что после небольшого руководства с моим решением.Замок Виндзор Замена фабрики

Вот моя реализация:

* обновлена ​​регистрация & DB вызов

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 (Transfer Object Data)

3 : Создайте агента с вызовом в базу данных.

Я решил поместить все эти функции в завод, поскольку он, похоже, соответствует законопроекту, однако я не совсем уверен, что это правильный или лучший способ выполнить это.

Вопрос в том, можно ли использовать все 3 сценария создания в заявлении регистра контейнера DI и полностью исключить конкретную фабричную реализацию, так что у меня больше нет класса AgentFactory, а только интерфейса IAgentFactory.

Другой вопрос, который у меня есть относительно этой реализации, можно сделать вызов, так что если я попрошу объект агента, Windsor сначала сделает вызов на заводе и вернет объект, созданный с завода, а не создаст объект без ссылки на завод. т.е.

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

С CallStack:

Container -> AgentFactory -> Создать (66) -> возвращает средство от завода.

Какой Виндзор будет перехватывать и автоматически использовать завод для создания экземпляра. Тем не менее, я попробовал это, и он не использовал фабрику для ее создания, он просто пошел и создал Агента, не ссылаясь на завод.

У меня было это, но он не вызывает методы фабрики, которые я определил.

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

Совет приветствуется, спасибо.

ответ

2

Типичная фабрика предназначена для создания экземпляра «поведение», а не экземпляра «данных».

Вы не регистрируетесь в контейнере как «модельный» компонент, но готовы к работе с моделью. Другими словами, вы регистрируетесь в контейнере всего, кроме модели.

Вы AgentFactory должны быть зарегистрированы в контейнере, но это не «Типичная фабрика». Вы можете использовать TF для целей «поздней зависимости».

Я предпочитаю быть более развязанным с моим дизайном, а также более «единоличной ответственностью». AgentFactory не скроет репозиторий (в соответствии с вашим созданием с db) на заводе: вместо этого я передам datareader как параметр Create.

+0

Репозиторий был последней минутой. Я считал, что, поскольку я могу создавать экземпляры с пустым конструктором, а также с DTO, мне бы хотелось, чтобы он запросил базу данных и, если возможно, извлек экземпляр. – Craig

+0

Использование шаблона репозитория AgentyFactory будет зависимым от репозитория, чтобы создать агрегатор/объект модели. В sql-сценарии репозиторий передаст sqldatareader на фабрику, чтобы получить экземпляр модели – Crixo

+0

. Я уже поставил свой репозиторий под контроль контейнера DI, просто не думал ссылаться на него как таковой. Чтобы сохранить его в отдельной библиотеке, я использовал другой контейнер DI. Тем не менее, я уверен, что я могу его учесть. Я переработаю этот пример, чтобы в кратчайшие сроки высказать ссылку на базу данных. – Craig

Смежные вопросы