2012-04-03 10 views
7

tengo la siguiente interfazMapeo entre T -> iHandler <T>

public interface IHandler<T> 
{ 
    void Handle(T myObject); 
} 

Me gustaría tener una clase con bodegas HandlersManager una asignación entre los tipos de objetos a su correspondiente controlador, pero no estoy seguro cómo se supone que debo definir el objeto que contiene esta asignación.

Por ejemplo, lo que me gustaría tener es la siguiente:

typeof(string) --> instance of IHandler<string> 
typeof(MyClass) --> instance of IHandler<MyClass> 

Lo mejor que tengo hasta ahora era definir Dictionary<Type, object> para el mapeo, pero en este caso tendría que emitir el valor a IHandler<T> cada vez que lo tengo.

¿Hay alguna solución mejor o algo que haya echado de menos por completo?

+1

Si '' iHandler heredada 'IHandler' entonces usted podría tener un diccionario de' 'todo lo que sucede con' IEnumerable' – Jodrell

+2

@Jodrell Como 'IHandler' sería una interfaz vacía, esto es lo mismo como usar 'object', ya que el molde aún es necesario. –

Respuesta

5

Eso es lo mejor que se puede obtener con solo una interfaz genérica IHandler<T>.

el fin de explorar más opciones, podríamos definir una versión no genérica de la interfaz:

public interface IHandler 
{ 
    void Handler(object myObject); 
} 

entonces también podría definir una clase base abstracta genérico que implementa tanto IHandler<T> y IHandler:

public abstract class BaseHandler<T> : IHandler, IHandler<T> 
{ 
    public abstract void Handle(T myObject); 

    void IHandler.Handle(object myObject) 
    { 
     ((IHandler<T>)this).Handle((T) myObject); 
    } 
} 

en este punto se puede tener una IDictionary<Type, IHandler> y se puede llamar directamente IHandler.Handle en los valores se tira de ella:

var obj = /* whatever */ 
dictionary[obj.GetType()].Handle(obj); 

Por otro lado, ahora tenemos una interfaz adicional y una clase base abstracta para ocultar un molde del código de "usuario", que no suena muy impresionante.

10

Sospecho que está utilizando esto para resolver dependencias. En su lugar, use un contenedor dedicado que manejará estos problemas por usted.

Si no quieres hacer eso, usted quiere algo como esto:

Dictionary<Type, object> dictionary; 

IHandler<T> Resolve<T>() { 
    return (IHandler<T>)dictionary[typeof(T)]; 
} 

No hay ninguna otra manera con los genéricos.

¿Hay alguna solución mejor o algo que haya echado de menos por completo?

No, pero las clases de gerente generalmente son olores de código. Ten cuidado.

+0

Parece más una clase de fábrica que una clase de gerente no específica, así que no creo que haya un olor aquí. – Rup

+1

@Rup: Francamente, ninguno de nosotros conoce el uso sin ver el contexto. Él lo llamó administrador, y parece una resolución. Esto es un olor porque si tengo una clase que use este administrador, no sé si está resolviendo 'IHandler 'concreto, y por lo tanto, no sé de qué' IHandler 's depende. – jason

Cuestiones relacionadas