Я использую Типичный завод, поставленный Виндзорским замком 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>());
Совет приветствуется, спасибо.
Репозиторий был последней минутой. Я считал, что, поскольку я могу создавать экземпляры с пустым конструктором, а также с DTO, мне бы хотелось, чтобы он запросил базу данных и, если возможно, извлек экземпляр. – Craig
Использование шаблона репозитория AgentyFactory будет зависимым от репозитория, чтобы создать агрегатор/объект модели. В sql-сценарии репозиторий передаст sqldatareader на фабрику, чтобы получить экземпляр модели – Crixo
. Я уже поставил свой репозиторий под контроль контейнера DI, просто не думал ссылаться на него как таковой. Чтобы сохранить его в отдельной библиотеке, я использовал другой контейнер DI. Тем не менее, я уверен, что я могу его учесть. Я переработаю этот пример, чтобы в кратчайшие сроки высказать ссылку на базу данных. – Craig