¡Hola!
Hoy vamos a ver cómo configurar nuestro contenedor IoC (con Ninject) a través de archivos XML. Esto puede ser útil en ciertas ocasiones, típicamente cuando queremos cambiar ciertas cosas sin tener que recompilar la aplicación.
Vamos a ver un ejemplo sencillo. Nos imaginamos que tenemos un servicio encargado de enviar cierta información de la aplicación, que normalmente se enviará por mail, pero en otras ocasiones queremos que se envíe por otro sistema. Como he dicho, el ejemplo es sencillo, que no por ello es buen ejemplo 🙂
Tendríamos algo así:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | public interface IDataSender { void SendData(); } public class EmailDataSender : IDataSender { public void SendData() { Console.WriteLine("Enviamos información a través de email"); } } public class AlternativeDataSender : IDataSender { public void SendData() { Console.WriteLine("Enviamos información a través de otro sistema"); } } |
Lo primero que vemos es que no, no es gran ejemplo… Luego, lo típico, una interfaz que define el contrato y dos implementaciones, la de envío por mail y el envío alternativo.
También tendríamos configurado Ninject más o menos así:
1 2 3 4 5 6 7 | public class Composer: NinjectModule { public override void Load() { this.Bind<IDataSender>().To<EmailDataSender>(); } } |
Todo perfecto, pero, ¿y si queremos que alguien pueda cambiar el tipo de IDataSender? Una de las opciones es la que vamos a ver, el poder configurar ese Binding a través de un archivo XML.
Vamos a añadir un nuevo paquete a nuestro proyecto, Ninject.Extensions.XML, y posteriormente un archivo XML a nuestro proyecto (en mi caso le voy a llamar ComposerXML.xml).
1 2 3 4 | <module name="ComposerXML"> <bind service="XMLNinjectSample.IDataSender, XMLNinjectSample" to="XMLNinjectSample.AlternativeDataSender, XMLNinjectSample" /> </module> |
Donde:
module>name: Es nuestro nombre único (ComposerXML por ejemplo).
Cada nodo bind es el equivalente a this.Bind<>().To<>(), donde el atributo service es «MyNamespace.IMyService, MyAssembly» y el atributo to es «MyNamespace.MyServiceImplementation, MyAssembly».
Ahora, nuestra clase Composer la deberíamos dejar de la siguiente forma:
1 2 3 4 5 6 7 | public class Composer: NinjectModule { public override void Load() { this.Kernel?.Load("ComposerXML.xml"); } } |
Si el archivo ComposerXML.xml lo añadís al proyecto, no olvidéis marcar en las propiedades del archivo que se copie en el directorio de salida.
Ahora vamos a ver un ejemplo de cómo usarlo:
1 2 3 4 5 6 7 8 9 10 | class Program { static void Main(string[] args) { var composer = new StandardKernel(new Composer()); var dataSender = composer.Get(); dataSender.SendData(); Console.ReadLine(); } } |
Compilamos el programa, y nos vamos al directorio de salida del mismo.
Como vemos en las imágenes, dependiendo de cómo tengamos configurado el archivo XML, usaremos EmailDataSender o AlternativeDataSender.
Eso es todo, ¡saludos!
2 thoughts on “Ninject. Configurar contenedor desde XML”