Я пытаюсь создать несколько универсальных фабрик для своих сервисных фабрик и фабрик dao, и у меня есть некоторые ограничения.
Обычно мои фабрики сервисов и дао выглядят так:
public static class PersonServiceFactory
{
private static PersonService personService;
public static PersonService GetInstance()
{
if (personService == null)
{
PersonDao personDao = PersonDaoFactory.GetInstance();
personService = new PersonService(personDao);
}
return personService;
}
}
public static class PersonDaoFactory
{
private static PersonDao personDao;
internal static PersonDao GetInstance()
{
if (personDao == null)
{
personDao = new PersonDao();
}
return personDao;
}
}
Затем я попытался создать общие фабрики:
public abstract class EntityDaoFactory<daoClass>
where daoClass : class, new()
{
private static daoClass factorySupportClass;
internal static daoClass GetInstance()
{
if (factorySupportClass == null)
{
factorySupportClass = new daoClass();
}
return factorySupportClass;
}
}
public abstract class EntityServiceFactory<serviceClass, daoClass>
where serviceClass : class, new()
where daoClass : class
{
private static serviceClass factorySupportClass;
internal static serviceClass GetInstance()
{
if (factorySupportClass == null)
{
//daoClass daoSupportClass = *how to get daoSupportClassfactory.GetInstance(); here?*
factorySupportClass = new serviceClass(daoSupportClass);
}
return factorySupportClass;
}
}
Таким образом, их можно было использовать так:
public static class PersonDaoFactory : Entities.EntityDaoFactory<PersonDao>
{
}
public static class PersonServiceFactory : Entities.EntityServiceFactory<PersonService, PersonDaoFactory>
{
}
Вот проблемы, с которыми я сталкиваюсь:
Невозможно использовать статический класс в качестве ограничения типа для дженериков, которые я пытался использовать для EntityServiceFactory, потому что без него я не знаю, как ввести соответствующий dao.
Фабрики не могут быть производными от общих фабрик, потому что я получаю такую ошибку:
Статический класс Persons.PersonDaoFactory не может быть производным от типа Entities.EntityDaoFactory. Статические классы должны быть производными от объекта.
- Пытался сделать их все нестатические классы с частными конструкторами, чтобы обойти это, но потом я получил:
'Persons.PersonService' должен быть неабстрактным типом с общедоступным конструктором без параметров, чтобы использовать его в качестве параметра 'serviceClass' в универсальном типе или методе 'Entities.EntityServiceFactory
Я смог прочитать, почему здесь встречается номер 3, но это все еще не решает моих проблем. Я получил работу DaoFactory, но она работает только в том случае, если конкретный DaoClass не нуждается в какой-либо инъекции зависимостей, иначе снова появится ошибка 3.
Есть ли способ заставить эти универсальные фабрики работать с использованием другого подхода, но при этом иметь возможность использовать DI?
ИЗМЕНИТЬ ----
Мне удалось добиться такой работы, но в ней есть некоторые странности. Сначала я создал интерфейс IEntityFactory:
public interface IEntityFactory<T>
where T : class
{
T GetInstance();
}
Затем изменил EntityDaoFactory на:
public abstract class EntityDaoFactory<daoClass> : IEntityFactory<daoClass>
where daoClass : class, new()
{
private static daoClass factorySupportClass;
public daoClass GetInstance()
{
if (factorySupportClass == null)
{
factorySupportClass = new daoClass();
}
return factorySupportClass;
}
}
Поэтому я мог передать соответствующие параметры типа и изменить EntityServiceFactory на:
public abstract class EntityServiceFactory<serviceClass, daoClass, daoFactoryClass>
where serviceClass : class, new()
where daoClass : class, new()
where daoFactoryClass : IEntityFactory<daoClass>, new()
{
private static serviceClass factorySupportClass;
public static serviceClass GetInstance()
{
if (factorySupportClass == null)
{
daoFactoryClass daoSupportFactory = new daoFactoryClass();
daoClass daoSupportClass = daoSupportFactory.GetInstance();
factorySupportClass = new serviceClass();
}
return factorySupportClass;
}
}
Итак, для конкретной реализации, такой как объект Person, вызовы выглядят так:
public class PersonDaoFactory : Entities.EntityDaoFactory<PersonDao>
{
}
public class PersonServiceFactory : Entities.EntityServiceFactory<PersonService, PersonDao, PersonDaoFactory>
{
}
Итак, сейчас это работает, но вот странности:
Вы можете создать экземпляр фабрики, которая требовалась (насколько я знаю, единственный способ сделать это?) Для EntityServiceFactory, но для тех, кто использует мой API, у них не было бы причин для этого, но они все равно могли.
Службы и DAO, у которых есть требования к зависимостям, теперь могут быть созданы без параметров, что нарушило бы созданные экземпляры методов класса (но мне пришлось сделать это, чтобы иметь возможность использовать его в качестве параметра типа). Они не должны даже когда-либо создавать экземпляры этих объектов, но теперь они могут делать это неправильно.
Также последняя проблема, о которой я только что подумал, заключается в том, что это решение на самом деле плохо справляется с переменным количеством зависимостей. Все еще задаетесь вопросом, есть ли для этого лучший подход?
Вывод: я думаю, что в конце концов, хотя это сработало, я отказался от большого количества заказов, чтобы иметь эту универсальную фабрику, которая не так гибка и не дает мне много, поэтому я, вероятно, не стал бы используйте его в этом случае из-за ограничений.
new()
). - person Austin Salonen   schedule 02.12.2011