Avoid public constructor somehow C# - 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!

Related

Create Microsoft.Extensions.Caching.Memory as a Singleton class

Im trying to use Microsoft.Extensions.Caching.Memory as singleton class in Asp.net MVC 5.
Problem is with each call the Instance Variable returns null and class reinstantiating it
self.(old value of Cache will be deleted)
this is my cache class :
public class CacheManagerHelper<TItem>
{
private static CacheManagerHelper<TItem> instance;
private static MemoryCache memoryCache;
private static object syncRoot = new();
private CacheManagerHelper() { }
public static CacheManagerHelper<TItem> Instance
{
get
{
if (instance == null)
{
instance = new CacheManagerHelper<TItem>();
memoryCache = new MemoryCache(new MemoryCacheOptions()
{
});
}
return instance;
}
}
private static ConcurrentDictionary<object, SemaphoreSlim> _locks = new ConcurrentDictionary<object, SemaphoreSlim>();
public async Task<TItem> GetOrCreate(object key, Func<Task<TItem>> createItem)
{
TItem cacheEntry;
if (!memoryCache.TryGetValue(key, out cacheEntry))
{
SemaphoreSlim mylock = _locks.GetOrAdd(key, k => new SemaphoreSlim(1, 1));
await mylock.WaitAsync();
try
{
if (!memoryCache.TryGetValue(key, out cacheEntry))
{
cacheEntry = await createItem();
var cacheEntryOptions = new MemoryCacheEntryOptions()
.SetPriority(Microsoft.Extensions.Caching.Memory.CacheItemPriority.NeverRemove)
.SetSlidingExpiration(TimeSpan.FromHours(24))
.SetAbsoluteExpiration(TimeSpan.FromHours(48));
memoryCache.Set(key, cacheEntry);
}
}
finally
{
mylock.Release();
}
}
return cacheEntry;
}
public T Get<T>(string key)
{
return (T)Convert.ChangeType(memoryCache.Get(key), typeof(T));
}
public void RemoveCache(string key)
{
memoryCache.Remove(key);
}
public static void ClearAllCacheObject()
{
IDictionaryEnumerator enumerator = HttpContext.Current.Cache.GetEnumerator();
while (enumerator.MoveNext())
HttpContext.Current.Cache.Remove(enumerator.Key.ToString());
}
}

How to cast object to type specified by Type variable

I am looking for a way to cast object variable into type with generic type argument specified by other variable of type Type.
I am limited to .NET 3.5, so no dynamic can be used :(
Main idea here is that I have access to a dictionary:
Dictionary<Type, object> data;
Data to that dictionary is added only in form of:
data.Add(T, new DataSub<T>(someValueOfTypeT));
The problem is, that when I'm trying to reverse the process:
foreach(var dataType in data.Keys) {
var dataValue = data[dataType];
ProcessDataValue(dataType, dataValue);
}
Now the question is how do I manage to cast object to DataSub?
Simplified DataSub.cs:
public class DataSub<T>
{
private T _cache;
public T Value {
get { return _cache; }
set { _cache = value; }
}
}
How it could work in ProcessDataValue:
public void ProcessDataValue(Type dataType, object dataValue)
{
var data = dataValue as DataSub<dataType>;
if (data == null) return;
AddProcessedDataValue(dataType, data.Value.ToString());
}
if you can do minimal changes to the classes you posted and if - as is showed in your example - what you would do with DataSub.Value is invoking ToString, may be you can obtain the result you need with
public interface IDataSub {
bool MatchesType(Type t);
object GetValue();
}
public class DataSub<T> : IDataSub {
private T _cache;
public T Value {
get { return _cache; }
set { _cache = value; }
}
public bool MatchesType(Type t) {
return typeof(T) == t; // or something similar, in order to handle inheritance
}
public object GetValue() {
return Value;
}
}
public class Client {
Dictionary<Type, IDataSub> data = new Dictionary<Type, IDataSub>() ;
public void AddData<T>(T someValueOfTypeT) {
data.Add(typeof(T), new DataSub<T> { Value = someValueOfTypeT });
}
public void UseData() {
foreach(var dataType in data.Keys) {
var dataValue = data[dataType];
ProcessDataValue(dataType, dataValue);
}
}
public void ProcessDataValue(Type dataType, IDataSub dataValue)
{
if(dataValue.MatchesType(dataType))
AddProcessedDataValue(dataType, dataValue.GetValue().ToString());
}
}
If the usage of DataSub.Value.ToString is only an example, and in the real world you need to access DataSub.Value using its type T, you should apply a broader reworking of you code.
What do you think about the following approach? This is an application of the pattern I like call set of responsibility (I wrote the linked post about this topic), a variation of GoF's chain of responsibility:
public interface IDataSub {
object GetValue();
}
public class DataSub<T> : IDataSub {
private T _cache;
public T Value {
get { return _cache; }
set { _cache = value; }
}
public object GetValue() {
return Value;
}
}
public interface IDataHandler {
bool CanHandle(Type type);
void Handle(object data);
}
public class Client {
private readonly Dictionary<Type, IDataSub> data = new Dictionary<Type, IDataSub>();
private readonly IList<IDataHandler> handlers = new List<IDataHandler>();
public void AddData<T>(T someValueOfTypeT) {
data.Add(typeof(T), new DataSub<T> { Value = someValueOfTypeT });
}
public void RegisterHandler(IDataHandler handler) {
handlers.Add(handler);
}
public void UseData() {
foreach(var dataType in data.Keys) {
handlers.FirstOrDefault(h => h.CanHandle(dataType))?.Handle(data[dataType].GetValue());
}
}
// Lambda-free version
// public void UseData() {
// foreach(var dataType in data.Keys) {
// for (int i = 0; i < handlers.Count; i++) {
// if (handlers[i].CanHandle(dataType)) {
// handlers[i].Handle(data[dataType].GetValue());
// break; // I don't like breaks very much...
// }
// }
// }
// }
}
class StringDataHandler : IDataHandler {
public bool CanHandle(Type type) {
// Your logic to check if this handler implements logic applyable to instances of type
return typeof(string) == type;
}
public void Handle(object data) {
string value = (string) data;
// Do something with string
}
}
class IntDataHandler : IDataHandler {
public bool CanHandle(Type type) {
// Your logic to check if this handler implements logic applyable to instances of type
return typeof(int) == type;
}
public void Handle(object data) {
int value = (int) data;
// Do something with int
}
}
This approach allow you to decouple data storage and data iteration logic from data-handling logic specific of different data-types: IDataHandler's implementations known what type of data they can handle and cast generic object reference to desired type. If you prefer, you can merge CanHandle method into Handle method, remving the former method and changing UseData to
public void UseData() {
foreach(var dataType in data.Keys) {
foreach(var handler in handlers) {
handler.Handle(dataType, data[dataType].GetValue())
}
}
}
and handler implementations to
class IntDataHandler : IDataHandler {
public void Handle(Type dataType, object data) {
if(typeof(int) == type) {
int value = (int) data;
// Do something with int
}
}
}
This variant is slightly more type-safe, because in the first variant was already possibile to call Handle method without a previus call to CanHandle.
If you liked this approach, you can bring it forward, simplifying your data structure and converting data from IDictionary to IList:
public interface IDataSub {
object GetValue();
}
public class DataSub<T> : IDataSub {
private T _cache;
public T Value {
get { return _cache; }
set { _cache = value; }
}
public object GetValue() {
return Value;
}
}
public interface IDataHandler {
bool CanHandle(object data);
void Handle(object data);
}
public class Client {
private readonly IList<IDataSub> data = new List<IDataSub>();
private readonly IList<IDataHandler> handlers = new List<IDataHandler>();
public void AddData<T>(T someValueOfTypeT) {
data.Add(new DataSub<T> { Value = someValueOfTypeT });
}
public void RegisterHandler(IDataHandler handler) {
handlers.Add(handler);
}
public void UseData() {
foreach(var dataItem in data) {
var value = dataItem.GetValue();
handlers.FirstOrDefault(h => h.CanHandle(value))?.Handle(value);
}
}
// Lambda-free version as above...
class StringDataHandler : IDataHandler {
public bool CanHandle(object data) {
// Your logic to check if this handler implements logic applyable to instances of String
return data is string;
}
public void Handle(object data) {
string value = (string) data;
// Do something with string
}
}
class IntDataHandler : IDataHandler {
public bool CanHandle(Type type) {
// Your logic to check if this handler implements logic applyable to instances of int
return type is int;
}
public void Handle(object data) {
int value = (int) data;
// Do something with int
}
}
The CanHandle-free variant can simplify IDataHandler interface and its implementation in this case, too...
I hope my answer can help you resolving you design scenario; I build it upon an approach I like very much, because it allows to apply subtype-specific logic to instances of different classe, given they share a common superclass (as object in my code samples).

Factory pattern with static registration

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();
}

Create generic List<T> in a Base class and use it in derived classes with different T

I have Base class and Manager class derived from it :
public class CBase<TC> where TC : class, new()
{
protected CBase() {}
protected static ConcurrentDictionary<object, Lazy<TC>> _instances = new ConcurrentDictionary<object, Lazy<TC>>();
public static TC GetInstance(object key)
{
return _instances.GetOrAdd(key, k => new Lazy<TC>(() => new TC())).Value;
}
}
public class CSeriesManager : CBase<CSeriesManager>
{
private List<CSeries.SSeries> _items = null;
public List<CSeries.SSeries> Series
{
get
{
if (_items == null) _items = new List<CSeries.SSeries>();
return _items;
}
}
}
I will have several manager classes and each of them will have field similar to List with a check for NULL in getter. Is it possible to make this field generic and move it to Base class without excess boxing / casting?
This is what I have so far :
public class CBase<TC> where TC : class, new()
{
protected CBase() {}
protected List<object> _items = new List<object>();
protected static ConcurrentDictionary<object, Lazy<TC>> _instances = new ConcurrentDictionary<object, Lazy<TC>>();
public static TC GetInstance(object key)
{
return _instances.GetOrAdd(key, k => new Lazy<TC>(() => new TC())).Value;
}
public List<TL> GetItems<TL>()
{
return _items.ConvertAll(x => (TL)x);
}
}
Does anybody have suggestions of how to improve / speed up it?
Is this what you want:
public class CBase<TC, LT> where TC : class, new()
{
protected CBase() {}
protected static ConcurrentDictionary<object, Lazy<TC>> _instances = new ConcurrentDictionary<object, Lazy<TC>>();
public static TC GetInstance(object key)
{
return _instances.GetOrAdd(key, k => new Lazy<TC>(() => new TC())).Value;
}
private List<LT> _items = null;
public List<LT> Series
{
get
{
if (_items == null) _items = new List<LT>();
return _items;
}
}
}
public class CSeriesManager : CBase<CSeriesManager, SSeries>
{
}

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));
}
}

Categories

Resources