Interface markers & dependency injection code smell?

4 views
Skip to first unread message

Israel García

unread,
Nov 23, 2016, 2:14:18 PM11/23/16
to improve-...@googlegroups.com
Hola grupo, tengo una pregunta:

Cuando usamos dependency injection normalmente usamos el par "Interface, TipoConcreto" para definir en el contenedor que tipo concreto se tiene que instanciar cuando la interface este presente en un constructor:

Services.RegisterTrasient<IEndPoint, concreteEndPoint>();

Entonces tengo un caso donde un proceso necesita usar una interface de tipo: IEndPoint pero no solo una, digamos que es un proceso que necesita varios endpoints:

constructor (ErrorEndPoint : IEndPoint , 
                    SuccessEndPoint: IEndPoint , 
                    TempEndPoint: IEndPoint)


Entonces todos van en el constructor, pero todos son de tipo IEndPoint, sin embargo yo quiero poder inyectar diferentes implementaciones de los endpoints para cada uno y solo tengo un IEndPoint en el contenedor, la solucion que viene en principio es crear interface markers, que no son mas que interfaces vacias para poder tener varias implementaciones del mismo tipo en el contenedor:

interface IErrorEndPoint : IEndPoint{
}
interface ISuccessEndPoint: IEndPoint{
}
interface ITempEndPoint: IEndPoint{
}

Services.RegisterTrasient<IErrorEndPoint, concreteEndPoint1>();
Services.RegisterTrasient<ISuccessEndPoint, concreteEndPoint2>();
Services.RegisterTrasient<ITempEndPoint, concreteEndPoint3>();

constructor (ErrorEndPoint : IErrorEndPoint, 
                    SuccessEndPoint: ISuccessEndPoint, 
                    TempEndPoint: ITempEndPoint)

Ahora, ESTO NO ME HUELE BIEN! siento que estoy haciendo un workarround, alguna sugerencia?

Saludos y happy thanks giving.
Israel.

Jazz@gmail

unread,
Nov 23, 2016, 2:23:48 PM11/23/16
to improve-...@googlegroups.com
que DI container estas usando?

generalmente ellos tienen una forma de resolver este problema sin necesidad de crear interfaces adicionales.

creo recuerdar que en unity se hacia decorando el constructor con un attribute [Dependency]



--

---
Has recibido este mensaje porque estás suscrito al grupo "Improve your code" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a improve-your-c...@googlegroups.com.
Para acceder a más opciones, visita https://groups.google.com/d/optout.

Niurka Perez Mitjans

unread,
Nov 23, 2016, 2:23:59 PM11/23/16
to improve-your-code
Hola Israel, depende del DI que estes usando, algunos tienen una forma de inyectar en determinadas condiciones por ejemplo con un nombre especifico. En ninject la sintaxis seria asi:


            container.Bind<IEndPoint >().To<IErrorEndPoint>().Named("Error")();
            container.Bind<IEndPoint >().To<ISuccessEndPoint>().Named("Success")();
            container.Bind<IEndPoint >().To<ITempEndPoint>().Named("Temp")();


luego tambien tienes que especificar el nombre en el constructor:  

constructor ([Named("Error")] IErrorEndPoint errorEndpoint, [Named("Success")] ISuccessEndPoint successEndpoint,  [Named("Temp")] ITempEndPoint tempEndpoint)


Espero que te de una idea para aplicar con el que estas usando tu.

Saludos
Niurka





--

---
Has recibido este mensaje porque estás suscrito al grupo "Improve your code" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a improve-your-code+unsubscribe@googlegroups.com.

Karel

unread,
Nov 23, 2016, 2:37:04 PM11/23/16
to improve-...@googlegroups.com
Can you define and inject dependencies by name? It looks a bit restrictive injecting dependencies by type only ... I remember I used to do this using Spring in Java.

Saludos,

Karel

Sent from my iPhone
--

---
Has recibido este mensaje porque estás suscrito al grupo "Improve your code" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a improve-your-c...@googlegroups.com.

Israel García

unread,
Nov 23, 2016, 3:05:09 PM11/23/16
to improve-...@googlegroups.com
Estoy usando el que viene con ASP.NET Core, se me ocurre que puedo usar un Factory Class y crearlo concretamente en el registro del tipo, algo asi:

class ProcessConfiguration : IProcessConfiguration {

  void ProcessConfiguration (ErrorEndPoint : IEndPoint, 
                                              SuccessEndPoint: IEndPoint, 
                                              TempEndPoint: IEndPoint
}

entonces en el Proceso:
constructor (IProcessConfiguration config)
Entonces al registrarlo tendria que llamar al factory con las implementaciones en concreto:
Services.RegisterTrasient<IProcessConfiguration>(
imp => new ProcessConfiguration (new ErrorEndPoint(), 
                                                        new SuccessEndPoint(),
                                                        new TempEndPoint())
En realidad el problema se mantiene porque si los EndPoints tienen otras dependencias tendria que pasarselas concretamente.

.... sigo pensando....



Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a improve-your-code+unsubscribe@googlegroups.com.

Para acceder a más opciones, visita https://groups.google.com/d/optout.

--

---
Has recibido este mensaje porque estás suscrito al grupo "Improve your code" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a improve-your-code+unsubscribe@googlegroups.com.

Karel Alfonso

unread,
Nov 23, 2016, 6:31:02 PM11/23/16
to improve-...@googlegroups.com
Hola Israel,
 
   Quiza con un poco mas de info sobre el context donde estas tratando de aplicar este disen~o y la funcion que juegan cada uno de tus IEndPoint seria mas facil debatir. Basado en esto aqui te van mas ideas:

- Empieza simple (si es un green field project) y define tus dependencias en la configuracion de la aplicacion.
Si solamente tienes una implementacion de ErrorEndPoint, SuccessEndPoint and TempEndPoint you usaria clases concretas (aun cuando implementen IEndPoint interface) . Tu DI framework permite inyectar clases concretas? Recuerdo que en Spring/Java era posible ...

- ASP.NET core es bastante simple y la mayoria de los ejemplos usan autowiring by type que funciona en algunos casos simples pero es restrictivo (Espero que el ejemplo de Nelyuska te ayude pues es la mejor solucion). 

 - Considera usar otro DI framework (si es que realmente va a adicionar valor a tu proyecto) como autofac(recomendado por un colega) que brinda otras formas de configurar las dependencies 


En general yo trataria de evitar que el DI framework dicte como debo disen~ar las componentes de la aplicacion. 

Saludos,

Karel


Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a improve-your-c...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages