I have a generic interface with two type parameters with severe generic constraints, and several implementations for different combinations.
public interface IResolver<TIn, TOut> where ... {...}
I want to create a (static) resolver factory that will store instances of the known implementations, and just serve them, along the lines:
public static ResolverFactory{
public static IResover<TIn, TOut> GetResolver<TIn, TOut> where ... ()
{
//access some storage dictionary to return the correctly typed instance
}
}
How can I create such a containter, that will store both IResover<Entity1, Entity2>
and IResolver<Entity3, Entity4>
?
One option I can think of is to use a separate non-generic "marker" interface like:
public interface IResolver {}
public interface IResolver<TIn, TOut> : IResolver where ....
{...}
and use
Dictionary<Type, Dictionary <Type, IResolver>> storage;
public RegisterResolver(IResolver resolver)
{
//add to storage - how?
}
but this scenario basically invalidates the constraints put on the generic parameters. Also when adding the IResolver
, getting the generic types of the IResolver<TIn, TOut>
is more or less impossible.
Is there a better solution to this?
There may be something obvious I'm missing in your question, because I don't understand where the issue is.
First, I declare a IResolver<TIn, TOut>
interface with a constraint:
public interface IResolver<TIn, TOut>
where TIn : Stream
{
}
Then, I create a ResolverFactory
, where the constraints are enforced by both the RegisterResolver
and GetResolver
method. The way the objects are actually stored doesn't matter, because the storage isn't exposed outside of the class. The encapsulation maintains the consistency:
public static class ResolverFactory
{
private static Dictionary<Type, object> storage = new Dictionary<Type, object>();
public static void RegisterResolver<TIn, TOut>(IResolver<TIn, TOut> resolver) where TIn : Stream
{
storage[typeof(IResolver<TIn, TOut>)] = resolver;
}
public static IResolver<TIn, TOut> GetResolver<TIn, TOut>() where TIn : Stream
{
return storage[typeof(IResolver<TIn, TOut>)] as IResolver<TIn, TOut>;
}
}
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments