Фабричный шаблон со статическим оформлением
У меня возникла проблема при попытке зарегистрировать мои типы, используя их статические конструкторы, со следующей фабрикой:
public class Factory<T>
{
public static Factory<T> Instance { get { return _instance; } }
private static Factory<T> _instance = new Factory<T>();
private Factory() { }
static Factory() { }
static Dictionary<string, Type> _registeredType = new Dictionary<string, Type>();
public void Register(string id, T obj)
{
if (obj.GetType().IsAbstract || obj.GetType().IsInterface)
throw new ArgumentException("Cannot create instance of interface or abstract class");
_registeredType.Add(id, obj.GetType());
}
public T Create(string id, params object[] parameters)
{
Type type;
if(!_registeredType.TryGetValue(id, out type))
throw new UnsupportedShapeException(id);
return (T)Activator.CreateInstance(type, parameters);
}
}
Тогда, если я использую статический конструктор для регистрации, он не работает:
public interface IShape
{
string print { get; }
}
public class Circle : IShape
{
static Circle()
{
Factory<IShape>.Instance.Register("Circle", new Circle());
}
public string print
{
get
{
return "Circle";
}
}
}
Куда я иду не так? Фабрика, кажется, настроена нормально, но я просто не могу заставить работать ctor. Приветствия.
2 ответа
Это не ответ, а совет. Во-первых, когда вы используете универсальный класс, на самом деле CLR создает класс для каждой реализации. Эти классы будут иметь разные статические переменные, и вы не можете использовать одну фабрику для всех классов. Хорошей новостью является то, что вы можете использовать обобщенные методы вместо обобщенного класса. И вам даже не нужно создавать экземпляр T
объект:
public class Factory
{
public static Factory Instance { get { return _instance; } }
private static Factory _instance = new Factory();
private Factory() { }
static Dictionary<string, Type> _registeredType = new Dictionary<string, Type>();
public void Register<T>(string id)
{
var type = typeof(T);
if (type.IsAbstract || type.IsInterface)
throw new ArgumentException("Cannot create instance of interface or abstract class");
_registeredType.Add(id, type);
}
public T Create<T>(string id, params object[] parameters)
{
Type type;
if(!_registeredType.TryGetValue(id, out type))
throw new UnsupportedShapeException(id);
return (T) Activator.CreateInstance(type, parameters);
}
}
Теперь вы можете использовать Factory
регистрировать и разрешать объекты:
Factory.Instance.Register<Circle>("Circle");
var firstCircle = Factory.Instance.Create<Circle>("Circle");
var secondCircle = Factory.Instance.Create<IShape>("Circle");
Я не уверен на 100%, что знаю, что вы собираетесь делать, однако, вероятно, было бы лучше создать классы контроллера, содержащие ваши фабричные экземпляры. Однако внедрение конструктора не будет работать со статическими классами или потомками.
public static class StaticFactoryClassController
{
private static readonly IStaticFactoryService service=AppServiceFactory.Instance.Create<IStaticFactoryService>();
public static void DoSomething()
{
Service srv = new StaticFactoryClassService(service);
srv.DoSomething();
}
}
И с этим вы могли бы создать класс обслуживания--
public class StaticFactoryClassService
{
private readonly IStaticFactoryService service;
public StaticFactoryClassService(IStaticFactoryService service)
{
this.service = service;
}
public void DoSomething()
{
this.service.DoSomething();
}
}
И, наконец, ваш обязательный интерфейс
public interface IStaticFactoryService
{
DoSomething();
}