Factory pattern with static registration - c#

I'm having a problem when trying to register my types using their static constructors, with the following factory:
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);
}
}
Then if I use a static constructor for registration it doesn't work:
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";
}
}
}
Where am I going wrong? The factory appears to set up fine but I just can't get the ctor to work. Cheers.

It's not an answer but an advice. First, when you use generic class actually CLR creates class for every implementation. This classes will have different static variables and you can not use one factory for all classes. The good news is that you can use generic methods instead of generic class. And you even do not need to create an instance of T object:
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);
}
}
Now you can use Factory to register and resolve objects:
Factory.Instance.Register<Circle>("Circle");
var firstCircle = Factory.Instance.Create<Circle>("Circle");
var secondCircle = Factory.Instance.Create<IShape>("Circle");

I am not 100% sure I know what you are going after, however, it would probably be best to make controller'esqe classes that contain your factory instantiation. However, constructor injection will not work on static classes or descendants.
public static class StaticFactoryClassController
{
private static readonly IStaticFactoryService service=AppServiceFactory.Instance.Create<IStaticFactoryService>();
public static void DoSomething()
{
Service srv = new StaticFactoryClassService(service);
srv.DoSomething();
}
}
And with that you could create a service class--
public class StaticFactoryClassService
{
private readonly IStaticFactoryService service;
public StaticFactoryClassService(IStaticFactoryService service)
{
this.service = service;
}
public void DoSomething()
{
this.service.DoSomething();
}
}
And finally your binding interface--
public interface IStaticFactoryService
{
DoSomething();
}

Related

How to implement a thread safe singleton dictionary class for caching?

I am trying to implement a thread safe dictionary singleton class for caching purpose.
namespace SingletomDict
{
public sealed class MySingleton:IDisposable
{
private static readonly Lazy<MySingleton> coll = new Lazy<MySingleton>(() => new MySingleton());
private static Dictionary<string, object> mycoll;
public static MySingleton Instance
{
get
{
return coll.Value;
}
}
private MySingleton()
{
mycoll = new Dictionary<string, object>();
}
private void SetProperty<T>(string name, T value)
{
mycoll.Add(name, value);
}
private object GetProperty(string name)
{
object value = mycoll[name];
return value;
}
public dynamic this[string index]
{
get { return GetProperty(index); }
set { SetProperty(index, value); }
}
public void ReSet()
{
mycoll = new Dictionary<string, object>();
}
}
In the main method, I will be invoking the object as
MySingleton.Instance["LS"] = "AAA";
MySingleton.Instance["AB"] = "BBB";
MySingleton.Instance.ReSet();
I did some research to find the correct implementation. But I couldn't find the appropriate example. Thanks
First declare an interface that describes how you want to use this. Perhaps ICache with a get and set method. (I'd steer clear of dynamic.)
public interface ICache
{
T Get<T>(string key);
void Set(string key, object value);
}
Then write an implementation. Your implementation doesn't need to specify what the internals are.
public class Cache : ICache
{
private readonly ConcurrentDictionary<string, object> _cache
= new ConcurrentDictionary<string, object>();
public T Get<T>(string key)
{
object cached;
if(_cache.TryGetValue(key, out cached) && cached is T)
{
return(T) cached;
}
return default(T);
}
public void Set(string key, object value)
{
_cache.AddOrUpdate(key, value, (s, o) => value);
}
}
If you want to make this a singleton, you can make the constructor private and create a static singleton instance. I would lean toward not doing that. It's better for other classes to depend on the ICache interface than on the implementation, and an interface doesn't have static methods.
Depending on the interface means that you can substitute it with different implementations, like one that depends on MemoryCache.
public class InMemoryCache : ICache
{
private readonly MemoryCache _cache = MemoryCache.Default;
public T Get<T>(string key)
{
var cached = _cache[key];
return cached is T ? (T) cached : default(T);
}
public void Set(string key, object value)
{
_cache[key] = value;
}
}
If you use a dependency injection (IoC) container you can tell it which implementation of ICache to use for a class that needs an instance of it, and you can specify that the same instance should be provided each time. That way you get to use a single instance of your class as if it was a singleton without having to code it as a singleton.

Proper run-time construction pattern for large number of objects

What is the best way to create derived objects at run-time while adhering to LSP and always keeping the objects in a valid state.
I'm fairly new to construction patterns such as Factory and Builder and most of the examples I find are very simplistic. Here is my scenario:
I have one base class (some things left out for brevity):
public abstract BaseClass
{
public string Property1 { get; set ... null guard; }
public string Property2 { get; set ... conditional null guard; }
public virtual bool RequiresProperty2 => false;
protected BaseClass(string property1)
{
null guard
Property1 = property1;
}
}
I have 50+ derived classes. Some of which require prop2 some of which don't. The ones that require prop2 have a constructor that forces prop2 to be passed in, enforcing that all BaseClass derived objects are in a valid state upon construction. I'm also trying to adhere to LSP and I'm using Castle Windsor for dependency injection.
The solution I've come up with is to create a factory that returns a builder:
public interface IFactory
{
IBuilder Create(string type);
}
public interface IBuilder
{
IBuilder SetProperty1(string property);
IBuilder SetProperty2(string property);
BaseClass Build();
}
The concrete implementation of the factory loads all the types that inherit from BaseClass through reflection. When you call Factory.Create(...) you pass it a string which is the string name of the type you want to create. Then the factory creates a builder passing the appropriate Type to the builder's constructor. The builder looks like so:
public sealed class ConcreteBuilder : IBuilder
{
private static Type ClassType = typeof(BaseClass);
private static readonly ConcurrentDictionary<Type, Delegate>
ClassConstructors = new ConcurrentDictionary<Type, Delegate>();
private readonly Type type;
private string property1;
private string property2;
public ConcreteBuilder(Type type)
{
if (type == null) throw new ArgumentNullException(nameof(type));
if (!type.IsSubclassOf(ClassType))
{
throw new ArgumentException("Must derive from BaseClass.");
}
this.type = type;
}
public IBuilder SetProperty1(string property)
{
this.property1 = property;
return this;
}
public IBuilder SetProperty2(string property)
{
this.property2 = property;
return this;
}
public BaseClass Build()
{
var arguments = BuildArguments();
Delegate ctor;
if (ClassConstructors.TryGetValue(this.type, out ctor))
{
return (BaseClass)ctor.DynamicInvoke(arguments);
}
return (BaseClass)GetConstructor(arguments).DynamicInvoke(arguments);
}
private object[] BuildArguments()
{
var args = new List<object>();
if (!string.IsNullOrEmpty(this.property1))
{
args.Add(this.property1);
}
if (!string.IsNullOrEmpty(this.property2))
{
args.Add(this.property2);
}
return args.ToArray();
}
private Delegate GetConstructor(object[] arguments)
{
var constructors = this.type.GetConstructors();
foreach (var constructor in constructors)
{
var parameters = constructor.GetParameters();
var parameterTypes = parameters.Select(p => p.ParameterType).ToArray();
if (parameterTypes.Length != arguments.Length + 1) continue;
if (!parameterTypes.Zip(arguments, TestArgumentForParameter).All(x => x))
{
continue;
}
var parameterExpressions = parameters.Select(p => Expression.Parameter(p.ParameterType, p.Name)).ToArray();
var callConstructor = Expression.New(constructor, parameterExpressions);
var ctor = Expression.Lambda(callConstructor, parameterExpressions).Compile();
ClassConstructors.TryAdd(this.type, ctor);
return ctor;
}
throw new MissingMethodException("No constructor found");
}
private static bool TestArgumentForParameter(Type parameterType, object argument)
{
return (argument == null && !parameterType.IsValueType) || (parameterType.IsInstanceOfType(argument));
}
}
Is there a better way to do this? Am I going about this the right way? I know DynamicInvoke is slow. Should I be going about this differently?

Avoid public constructor somehow C#

I've just created some kind of generic repository, it seems to be working, my only problem is, is there any solution to avoid to use public constructor in classes what has to be instantiated to the repository?
My code is here:
public sealed class repository
{
private static readonly object _lock = new object();
private static readonly object _syncroot = new object();
private static volatile repository _instance;
private static readonly Dictionary<int, object> _dict
= new Dictionary<int, object>();
private repository()
{
}
public static repository instance
{
get
{
if (_instance == null)
{
lock (_lock)
{
if (_instance == null) _instance = new repository();
}
}
return _instance;
}
}
public void allocate<Tc>(int id, object constructor_param) where Tc : Irepository<Tc>, new()
{
lock (_syncroot)
{
if (!_dict.ContainsKey(id))
{
var n = new Tc();
_dict.Add(id, n.New(constructor_param));
}
}
}
public T get<T>(int id)
{
lock (_syncroot)
{
return (T) _dict[id];
}
}
}
public interface Irepository<out T>
{
T New(object constructor_param);
}
public class RpSupportedClass : Irepository<RpSupportedClass>
{
public object _constructor_param;
private RpSupportedClass(object constructor_param)
{
_constructor_param = constructor_param;
}
public RpSupportedClass()
{
}
public RpSupportedClass New(object constructor_param)
{
return new RpSupportedClass(constructor_param);
}
}
So the problem is that I have to create a default public constructor:
public RpSupportedClass()
{
}
...because of type parameter. I need type parameter by this way because I would like to use parameter in class instantiate sometimes.
Is there any way out?
Thank you!

Dictionary of <Type, List<Type>>

I want to implement a wrapper class for a Dictionary that maps a Type to a generic List of that Type. For example:
**Key** **Value**
typeof(InterfaceA), List<InterfaceA>
typeof(InterfaceB), List<InterfaceB>
typeof(MyClass), List<MyClass>
...
I then want to interact with the wrapper class by using types.
public void NewEntry<T>()
{
MyDict.Add(typeof(T), new List<T>());
}
public List<T> GetEntry<T>()
{
return MyDict[typeof(T)];
}
public void RemoveEntry<T>()
{
MyDict.Remove(typeof(T));
}
Is there any elegant way to do this?
EDIT: to clarify, the point of this is so that with
GetEntry<MyInterface>()
the items in the list are guaranteed to follow the contract of MyInterface. Each entry would have a different Type key, and each List of items would follow the contract of that Type.
You could use the following static class
public static class GenericLists
{
private static Dictionary<Type, object> MyDict = new Dictionary<Type, object>();
public static void NewEntry<T>()
{
MyDict.Add(typeof(T), new List<T>());
}
public static List<T> GetEntry<T>()
{
return (List<T>)MyDict[typeof(T)];
}
public static void RemoveEntry<T>()
{
MyDict.Remove(typeof(T));
}
}
Or you could use
public class GenericLists<T>
{
private Dictionary<Type, List<T>> MyDict = new Dictionary<Type, List<T>>();
public void NewEntry()
{
MyDict.Add(typeof(T), new List<T>());
}
public List<T> GetEntry()
{
return MyDict[typeof(T)];
}
public void RemoveEntry()
{
MyDict.Remove(typeof(T));
}
}
if you really want to initialize it, but I think the static will work better.
If you're willing to store everything statically, you can use the type system:
static class MyDict {
private static class Data<T> {
public static readonly List<T> items = new List<T>();
}
public static List<T> Get<T>() { return Data<T>.items; }
public static void Add<T>(T item) { Data<T>.items.Add(item); }
}
Note that this makes it impossible to remove a key (you can't unload a type), although you can Clear() it.
You can do it as an instance-based class also (see below), but my preference, if it works for you, is to use a static variable in a static class as SLaks demonstrated in the "use the type system" post.
public class GenericTypeListDictionary
{
private readonly Dictionary<Type, object> _dictionaryOfLists = new Dictionary<Type, object>();
public List<T> NewEntry<T>()
{
var newList = new List<T>();
_dictionaryOfLists.Add(typeof(T), newList);
return newList;
}
public List<T> GetEntry<T>()
{
object value;
if (_dictionaryOfLists.TryGetValue(typeof(T), out value))
{
return (List<T>)value;
}
return null;
}
public void RemoveEntry<T>()
{
_dictionaryOfLists.Remove(typeof(T));
}
}

Why can't I return my object as its' interface?

I have a series of interface definitions, all of which compile (so my objects are composed correctly). The objects instantiate, as expected. However, when I try to return the object from its' underlying factory I get the following error:
ERROR:
Unable to cast object of type
'SampleLibrary.Domain.DataAcessors.Person.SQLDataAccessor' to type
'Common.Contracts.DataAccessors.IDataAccessorModel`2[SampleLibrary.Contracts.Models.IPerson,SampleLibrary.Domain.DataAccessors.Types.SqlServer]'.
Please keep in mind I am trying to return each instance as the IDataAccessor interface.
CODE:
public interface IDataAccessor<I, T>
{
T AccessType { get; }
}
public interface IDataAccessorModel<I, T> : IDataAccessor<I, T>
{
I Instance { get; }
IResult<string> Get(I instance);
IResult<string> Add(I instance);
IResult<string> Update(I instance);
IResult<string> Delete(I instance);
}
public class SQLDataAccessor : IDataAccessorModel<IPerson, IAccessType>
{
internal SQLDataAccessor(IResult<string> result)
{
_connectionString = "";
_result = result;
}
private readonly string _connectionString;
private IResult<string> _result;
public IAccessType AccessType { get { return new SqlServer(); } }
public IPerson Instance { get; private set; }
public IResult<string> Add(IPerson instance)
{
Instance = instance;
return _result;
}
public IResult<string> Get(IPerson instance)
{
Instance = instance;
return _result;
}
public IResult<string> Delete(IPerson instance)
{
Instance = instance;
return _result;
}
public IResult<string> Update(IPerson instance)
{
Instance = instance;
return _result;
}
}
public class FactoryDataAccess : IFactoryDataAccess
{
internal FactoryDataAccess() { }
public IDataAccessor<I, T> Create<I, T>()
{
var model = typeof(I);
var target = typeof(T);
if (model.IsAssignableFrom(typeof(IPerson)))
{
if (target == typeof(SqlServer)) {
var accessor = new Person.SQLDataAccessor(new Result());
// This next line FAILS!
return (IDataAccessorModel<I, T>)accessor;
}
}
throw new NotSupportedException("Type " + target.FullName + " and Source " + model.FullName + " is not supported.");
}
}
UPDATE:
Please keep in mind that IDataAccessorModel can be used by any desired DataAccess type you wish to define.
SQLDataAccessor implements IDataAccessorModel<IPerson, IAccessType>, so it would work only if <I, T> were <IPerson, IAccessType>. There is no guarantee about that, since the method is generic and I and T could be any type, so the cast fails.
Of course, since you're checking the types of I and T, you know the cast would be valid, but the compiler doesn't. You can trick it like this:
return (IDataAccessorModel<I, T>)(object)accessor;
However, since T has to be SqlServer, it doesn't make sense to make it a generic type parameter. And since I has to implement IPerson, there should be a constraint on it. So the method signature should be:
public IDataAccessor<I, T> Create<T>() where T : IPerson
It work for me if I declare SQLDataAccessor like this:
public class SQLDataAccessor : IDataAccessorModel<IPerson, SqlServer>
{
...
}
You are probably calling it like this
var factory = new FactoryDataAccess();
var da = factory.Create<IPerson, SqlServer>();
i.e. you call it with T being SqlServer. If you declare T as IAccessType in SQLDataAccessor it is not guaranteed that IAccessType would be SqlServer. Therefore the casting error. (However, SqlServer is guaranteed to be IAccessType as it probably implements it.)
SQLDataAccessor is not a generic class, but implements IDataAccessorModel<IPerson, IAccessType> exactly, so your method Create should return IDataAccessor<IPerson, IAccessType>, but you probably called it with other generic types.
Change SqlDataAccessor to:
public class SQLDataAccessor<I, T> : IDataAccessorModel<I, T>
{
internal SQLDataAccessor(IResult<string> result)
{
_connectionString = "";
_result = result;
}
private readonly string _connectionString;
private IResult<string> _result;
public T AccessType { get { return new SqlServer(); } }
public I Instance { get; private set; }
public IResult<string> Add(I instance)
{
Instance = instance;
return _result;
}
public IResult<string> Get(I instance)
{
Instance = instance;
return _result;
}
public IResult<string> Delete(I instance)
{
Instance = instance;
return _result;
}
public IResult<string> Update(I instance)
{
Instance = instance;
return _result;
}
}
You might want to limit I and T to the interfaces, so add a where constraint:
public class SQLDataAccessor<I, T> : IDataAccessorModel<I, T>
where I : IPerson
where T : IAccessType
The way you have it, I could be any type derived from IPerson and T is exactly of type SqlServer, which would cause the cast to fail since SQLDataAccessor implements the IDataAccessorModel with different parameters. You would need to have a more exact cast, such as:
return (IDataAccessorModel<IPerson, IAccessType>)accessor;

Categories

Resources