patrones patron inyección inyeccion ejemplo diseño dependencias c# .net dependency-injection mocking

c# - patron - Diferencia entre la inyección de dependencia y el marco de burla(Ninject vs RhinoMock o Moq)



patron de inyeccion (2)

Entonces, ¿cuál es la diferencia entre Ninject y un marco de burla como RhinoMock o moq? Busqué en Google esto pero todavía no está claro.


Ninject es una herramienta de inyección / inversión de control de dependencia. Se utiliza para gestionar las dependencias entre clases.

El ejemplo clásico es si tiene algo como un servicio o un repositorio de datos. En lugar de utilizar una clase concreta en toda la aplicación, puede pedirle al núcleo de Ninject que le proporcione una instancia de una interfaz. Esto significa que puede crear varias clases concretas que implementen la interfaz y cambiarlas en un solo lugar. Esto es extremadamente útil en las pruebas, pero va mucho más allá de eso. Muchos de los contenedores IoC, como Ninject no es una excepción, también harán cosas como administrar los ciclos de vida de la instancia y una gran cantidad de otras cosas. Diga que si quiere usar 1 repositorio por solicitud web, o una sola instancia de una clase, ese es el tipo de cosas que Ninject puede cuidar de usted de manera muy limpia.

Moq, RhinoMocks, etc. son marcos de simulacros, generan clases falsas para que afirmes que otras partes de la aplicación interactúan con ellos de la manera correcta. Estos solo son realmente útiles para realizar pruebas porque los objetos simulados no proporcionan ninguna funcionalidad más allá de informar cómo se accedió a ellos.

También puede consultar StructureMap - structuremap.net/structuremap - tienen algunos buenos artículos que describen el patrón y también Rob Conery hace episodios en IoC - http://www.asp.net/mvc/videos/aspnet-mvc-storefront-part-13-dependency-injection - y en Mocking - http://www.asp.net/mvc/videos/aspnet-mvc-storefront-part-12-mocking - que son un buen reloj y se describen mucho mejor de lo que puedo tratar cada uno.


Ninject es la inyección de dependencia para .NET.

RhinoMocks y Moq son ambos marcos burlones.

Ahora ambos no tienen nada que ver el uno con el otro. Realmente tuve problemas para entender ambos, así que aquí voy a tratar de explicar

Inyección de dependencia : es una implementación (llamémosla) de Inversión de Control. No confundas los dos. Usted está tomando el control de crear un objeto a partir de su código. Las dependencias, como por ejemplo un IRepository , no serían creadas por sus clases / código, sino que, en cambio, serían inyectadas por otra persona, un marco de inyección de dependencias.

Digamos que tienes

interface IUserRepository { string GetUserName(int id);//one method for simplicity }

Ahora tienes una implementación real:

class MyUserRepo : IUserRepository { string GetUserName(int id) { //grab your username from your data base here. } }

Ahora por todas partes, tendrás:

IUserRepository repo = new MyUserRepo();//this is bad!!

¿Por qué? Pregúntate por qué hiciste una interfaz en primer lugar? Así que puedes hacer frente al cambio . Bueno, ahora, cuando necesites cambiar tu repositorio a otra cosa. Tienes que reemplazar todas las líneas que tienen new MyUserRepo() .

Un método simple es utilizar un método de fábrica que es otra forma de IOC.

class RepoFactory { public static IUserRepository UserRepo { get {return MyUserRepo();} } }

Y úsalo así:

IUserRepository rep = RepoFactory.UserRepo;

Ahora, cuando tiene que cambiar su repositorio, solo tiene que cambiar su fábrica. La inyección de dependencia lleva esto al siguiente nivel haciendo todo el trabajo. No necesita cambiar el código en absoluto (o quizás algunas declaraciones).

IUserRepository repo; //this magically gets the right instance based on some config somewhere.

Un marco burlón : chico, esto fue como una ciencia espacial para mí. Pero el libro de Steven Sanderson tenía una explicación simple y brillante.

Seguimos con el IUserRepository .

Ahora tiene que probar algunos UI / Autenticación complicados, independientemente de lo que dependa de IUserRepository .

class UserDisplay : UserControl { UserDisplay(IUserRepository repo) {//display the username or something here.. } }

Ahora en tu prueba, cuando hagas de IUserRepository una instancia de MyUserRepo . ¡Si algo sale mal, no sabes qué salió mal! ¿Fue su control de usuario o su conexión de base de datos?

Usted quiere hacer la prueba más determinista como alguien dijo.

Así que haces un repositorio de usuarios falso.

class FakeUserRepo : IUserRepository { public string GetUserName(int id) { return "FakeUser"; } }

Así que ahora, cuando pasas este repo falso . Si su prueba falla, SABE que fue otra cosa, no la base de datos.

Mi ejemplo fue simple, pero si es un gran número de interfaces. Tendrá que escribir un montón de código falso , ¡es un montón de código inflado!

Así que puedes usar un marco burlón para escribir menos código aquí.

Moq usa una interfaz fluida y es bastante agradable. Usar Moq se vería así:

var fakeUserRepo = new Mock<IUserRepository>(); fakeUserRepo.Setup(f => f.GetUserName(It.IsAny<int>)).Returns("FakeUser"); //does the same thing as the class declaration fakeUserRepo.Object;//this returns fake object of type IUserRepository

Crear objetos falsos se vuelve mucho más fácil =)

Ahora espero que veas cómo puedes usar ambos a tu favor. Puede crear sus objetos falsos con un marco de burla, luego usar la inyección de dependencia para conectar los objetos correctos en el momento adecuado.

Para mis aplicaciones Silverlight más pequeñas, uso MEF (incorporado en .Net4) para inyección de dependencia. Y luego tengo poco #Ifdef en las declaraciones para qué clases Export (o exponer) en función de un símbolo #define . Así que solo cambio un #define y puedo cambiar mi aplicación para usar clases falsas aquí y allá.

Realmente espero que haya sido útil.