Autofac es un Ioc que podemos utilizar para aplicar DI en nuestra aplicación. Esto nos permitirá desacoplar nuestra aplicación de manera fácil y poder sustituir componentes de manera fácil. Veremos que es cada cosa.
DI e Ioc, básicamente se encargan de desacoplar nuestra aplicación, quitando dependencias entre proyectos al encargarse de instanciar los objetos y controlar su tiempo de vida. Aparte, como hemos comentado, al quitar dependencias y desacoplar los proyectos, nos permitirá sustituir componentes de manera más fácil.
Vale pero… ¿Qué es DI?
Dependency injection (DI en adelante) es, en pocas palabras, delegar la instanciación de objetos a otro componente de la aplicación, en nuestro caso será Autofac. Nosotros lo único que veremos es que no trabajaremos con objetos directamente, sino con interfaces de ellos. La manera de instanciar un objeto será mediante la inyección en el controlador, básicamente pondremos la interfaz que queremos utilizar y se la asignaremos a nuestra variable privada.
Un ejemplo de un controlador con DI es:
#region Attribute private readonly IInterfazDelObjecto _objeto; #endregion #region Constructors public DesignerManager(IInterfazDelObjecto objecto) { this._objeto = objeto; } #endregion
Y entonces, que es Ioc
Inversion of control (en adelante Ioc) es, como su propio nombre indica, la inversión de control. En lugar de invocar nuestro código, hay un componente que lo invoca por nosotros.
DI solo es una parte de un Ioc que se encarga de la instanciación de los objetos, esto nos permite configurarlo para que en cualquier punto de nuestro programa tengamos la misma instancia de un objeto, o que cada vez tengamos una instancia nueva,… Otro ejemplo sería, en caso de una aplicación de MVC, que la instancia del objeto sea igual por el ciclo de vida de una petición a un controller.
Necesito un ejemplo
Primero, vamos a crear una aplicación muy básica, yo he cogido un proyecto limpio de MVC donde he creado el controlador Home y su vista. Le he llamado forCode.Web.
Después agregamos 3 proyectos más de tipo librería de clases llamados forCode.Ioc, forCode.IService, forCode.Service.
Después creamos en IService una interfaz, IAutorService, con una función, DameElNombre, que nos devuelva un string.
Ahora, en el proyecto de Service creamos otro objeto que implemente la interfaz anterior, en mi caso AutorService: IAutorService, haciendo que devuelva “Eric”. Para ello tenemos que agregar la referencia al proyecto de IService.
La manera “sin DI” de acceder a la función, sería haciendo un:
var autorService = new AutorService(); autorService.DameElNombre();
Pero en lugar de eso, lo que haremos será que autofac lo haga por nosotros. Para ello instalamos el Nuget de Autofac que se llama “Autofac” y lo ponemos en los proyectos de Ioc y Web.
————
Tenemos otro paquete Nuget “Autofac ASP.NET MVC 5 Integration” que lo usaremos si queremos hacer una factoría de controladores, pero de momento no lo usaremos.
————
Añadimos al proyecto de Ioc las referencias a IService y Service. Aparte, creamos una clase static llamada Register (el nombre es libre) que se encargará de referenciar que clase va con que interfaz. La dejaremos tal que:
public static class Register { public static ContainerBuilder Builder { get; set; } public static ContainerBuilder RegisterTypes() { Builder = new ContainerBuilder(); RegisterServices(); return Builder; } private static void RegisterServices() { // Base // Other Builder.RegisterType<AutorService>().As<IAutorService>().InstancePerRequest(); } }
Luego explicare con calma los tipos de register que hay.
Hacerlo en un proyecto aparte nos servirá para poder reutilizarlo desde otros proyectos, pero sobre todo, porque así será este proyecto el que tenga las referencias a los proyectos y no nuestra web.
Añadimos la referencia del proyecto de Ioc y IService al proyecto web. Abrimos el GlobalAsax y en la función de Application_Start es donde tenemos que decirle a la aplicación que vamos a usar Autofac. Tenemos que añadir en la función el siguiente código:
// Obtenemos el contenedor de Autofac que hemos creado en la clase Register var builder = Register.RegisterTypes(); // de momento no vmaos ha poner una factoria de controladores pero si lo queremos usar desde // ahí tenemos que registrar los controladores que tenemos en la aplicación. builder.RegisterControllers(typeof(MvcApplication).Assembly).InstancePerRequest(); // Establecemos Autofac como “solucionador de dependencias” DependencyResolver.SetResolver(new AutofacDependencyResolver(builder.Build()));
Y solo nos quedaría ponerlo en el constructor del Controller de Home que nos tiene que quedas así:
#region Attributes private readonly IAuthor _author; #endregion #region Constructor public HomeController(IAuthor author){ this._author = author; } #endregion
Ahora solo tendríamos que crear una función en nuestro controlador llamando a la propiedad this_author.DameElNombre() y veríamos que nos retorna correctamente el nombre.
Con esto ya lo tendríamos, desde cualquier punto de la aplicación, inyectando el IAuthor, tendríamos una sola instancia pero… en nuestro caso, muy útil no es que sea.
Por eso en el siguiente post explicaré con un poco más de detalle autofac, sus tipos de registers y un ejemplo un poco más «útil»