Estoy usando una biblioteca de clases que pueden ser reutilizados por otros componentes. En esta biblioteca de clases estoy usando la unidad para la inyección de dependencia. Para esta clase de la biblioteca de crear un proyecto de prueba. El autor de la llamada también se presenta un proyecto de prueba. De una cosa estoy seguro acerca de la ubicación de los enlaces. Debo incorporar esto en la biblioteca de clase o debo hacerlo desde la aplicación de llamada?

  • Usted puede tener una mirada en p&p Enterprise Library. Se está utilizando la Unidad de debajo de las mantas y se inicializa el contenedor sin la interacción del usuario.
  • que no es del todo cierto, el punto de entrada de la aplicación (también conocido como el «usuario») tiene que inicializar un contenedor y registro de la empresa de la biblioteca de la unidad de extensión. Ver mi respuesta para un ejemplo de esto más adelante.
InformationsquelleAutor Patrick | 2012-04-17

4 Comentarios

  1. 8

    Este es un problema interesante. ¿Cómo se puede inyectar la dependencia de re-utilizable asambleas que no tienen un punto de entrada. Realmente me gustaría ver a otras personas de la respuesta.

    La inyección de dependencia es la responsabilidad de la de punto de entrada de la asamblea. Sin embargo, si usted tiene un montón de clases y conjuntos cada necesidad de DI, entonces es posible que tengan la izquierda para algunas clases/asambleas y la tarea se vuelve oneroso.

    Solución De Una

    El uso de convención sobre configuración. De atenerse a una regla de clase Foo la aplicación de IFoo, etc. Una gran cantidad de marcos DI tienen los medios para configurarlo mediante convenio.

    Solución de los dos

    Solución anterior no resuelve todos los problemas, ya que a veces es necesario parametrizar la configuración de la inyección. Aquí es cómo he resuelto el problema (especialmente para los ensamblados cargados por MEF y esto es para AutoFac):

    Creado una interfaz IIocInstaller donde contenedor (o el generador se pasa)

    public interface IIocInstaller
    {
        void Setup(ContainerBuilder builder);
    }

    Creado una asamblea atributo que banderas asambleas necesidad de DI:

    [AttributeUsage(AttributeTargets.Assembly)]
    public class ExportAssemblyAttribute : Attribute
    {
    }

    En cada asamblea, puedo crear una clase en la que se establezca DI:

    [assembly: ExportAssembly]
    namespace This.That
    {
    
        [Export(typeof(IIocInstaller))]
        public class IocInstaller : IIocInstaller
        {
            public void Setup(ContainerBuilder builder)
            {
                ....
            }
        }
    }

    A continuación, en el punto de entrada, tengo un código común que se ve a través de todos los ensamblados cargados (incluyendo MEFed) que tiene la asamblea de atributo y, a continuación, busque el tipo de aplicación de la IIocInstaller y, a continuación, Configuración de llamada en ellos.

    • Gracias por la sugerencia. Él me sacó de mis pensamientos patrón. Ahora estamos introduciendo una nueva configuración del proyecto. De esta manera, la clase de la biblioteca pueden utilizar diferentes implementaciones.
    • es un problema difícil. Los constructores estáticos no necesariamente funciona ya que podría ser tarde para DI, especialmente para dos paso de los contenedores como AutoFac.
    • En primer lugar este es un Autofac howto respuesta a una Unidad de la pregunta. También tiene una biblioteca de soporte de múltiples Coi/DI contenedores no debe ser difícil si los contenedores de apoyar el concepto de extensiones de una manera similar a la Unidad. Sólo se han dedicado extensiones de clase que utiliza el contenedor de IoC/DI implementador y, a continuación, el punto de entrada de la aplicación puede elegir la extensión que coincida con su elección de la Coi/DI.
  2. 27

    Sé que la respuesta ha sido elegido, sin embargo, creo que una parte de la Unidad está siendo pasado por alto. Ya que esta fue una específica Unidad pregunta pensé que señalar la UnityContainerExtension base de la clase que implementa el IUnityContainerExtensionConfigurator. Ahí está para biblioteca de API para extender a hacer que sea fácil para el punto de entrada de la aplicación que posee el Contenedor de tener una manera fácil de asegurarse de que su biblioteca se registra con el Contenedor correctamente, y permite la API propietario el control de lo que se registra y cómo.

    Este es utilizado por la Empresa de Microsoft Bibliotecas para este propósito.

    Voy a usar una biblioteca de Registro como un simple:

    public class LoggingUnityExtension : UnityContainerExtension
    {
        protected override void Initialize()
        {
            Container.RegisterType<ILogger, Logger>(new ContainerControlledLifetimeManager());
        }
    }

    A continuación, el punto de entrada de la aplicación hace esto:

    public class Bootstrapper : UnityBootstrapper
    {
        protected override void ConfigureContainer()
        {
            base.ConfigureContainer();
    
            Container.AddNewExtension<EnterpriseLibraryCoreExtension>();
            Container.AddNewExtension<LoggingUnityExtension>();
            //... 
        }
    
        //...
    }

    Ahora se han registrado Enterprise Library y la API de la biblioteca de Registro. Es muy sencillo para el punto de acceso de la aplicación con este método que es lo que cualquier biblioteca desarrollador debe tener como objetivo.

    • Puede que desee hacer referencia a la biblioteca de manera que la gente puede utilizar su ejemplo fácilmente. ¿Necesita la EnterpriseLibraryCoreExtension para que esto funcione?
    • Eso depende de tus necesidades, pero por lo general cuando se utiliza la Unidad y cualquiera de los EntLib Bloques tendrá que uso casi siempre. Recuerde que estas son fragmentos de código para mostrar ejemplos no es totalmente funcional código. Yo estado en mis comentarios que estoy usando Microsoft Enterprise Bibliotecas que debería ser suficiente para el ejemplo. Como para el ILogger y Registrador de aquellos que sólo se utilizan para mostrar cómo utilizar un recipiente de extensión que no es para mostrar cómo crear un Registrador. Que la aplicación no es relevante.
  3. 2

    Hacerlo desde la aplicación llamada pone más carga en la aplicación de llamada. Dejando la posibilidad de omitir la inicialización y se meten en problemas.

    Me gustaría hacerlo en la biblioteca de clase, por ejemplo, en un constructor estático.

    • Que no es una sabia elección. El punto de entrada de la aplicación debe poseer y controlar el contenedor, que es la razón por la unidad permite el registro de las extensiones y el UnityContainerExtension de la clase base para que sea fácil de implementar el IUnityContainerExtensionConfigurator de la interfaz. Ver mi respuesta para un ejemplo.
    • Este es un método simple que pueda funcionar en el entorno adecuado.
  4. 0

    O. K Crear una librería con nombre de Proyecto.Coi. Instalar la Unidad aquí. De referencia de las otras capas de la Coi de la biblioteca. Y la Coi de la Biblioteca a la capa de presentación. Crear una clase denominada UnityHelper.

    ///<summary>
    ///Bind the given interface in request scope
    ///</summary>
    public static class IocExtensions
    {
        public static void BindInRequestScope<T1, T2>(this IUnityContainer container) where T2 : T1
        {
            container.RegisterType<T1, T2>(new HierarchicalLifetimeManager());
        }
    
        public static void BindInSingletonScope<T1, T2>(this IUnityContainer container) where T2 : T1
        {
            container.RegisterType<T1, T2>(new ContainerControlledLifetimeManager());
        }
    }
    
    ///<summary>
    ///The injection for Unity
    ///</summary>
    public static class UnityHelper
    {
    
        public static IUnityContainer Start()
        {
            var container = BuildUnityContainer();
    
            DependencyResolver.SetResolver(new Unity.Mvc4.UnityDependencyResolver(container));
    
            return container;
        }
    
        ///<summary>
        ///Inject
        ///</summary>
        ///<returns></returns>
        private static IUnityContainer BuildUnityContainer()
        {
            var container = new UnityContainer();
    
            //register all your components with the container here
            //it is NOT necessary to register your controllers
    
            //Database context, one per request, ensure it is disposed
            container.BindInRequestScope<IMVCForumContext, MVCForumContext>();
            container.BindInRequestScope<IUnitOfWorkManager, UnitOfWorkManager>();
    
            //Bind the various domain model services and repositories that e.g. our controllers require         
            container.BindInRequestScope<ITopicService, TopicService>();
    
            container.BindInRequestScope<ITopicTagRepository, TopicTagRepository>();
    
            //container.BindInRequestScope<ISessionHelper, SessionHelper>();
    
            return container;
        }
    }

    Retirar el MvcForum proyecto. Hay MvcForm.La coi de la biblioteca de clases. La biblioteca pone otra Capa de referencias. Sólo hay una clase denominada UnityHelper.

    https://github.com/leen3o/mvcforum

    espero que esto sea wat que usted está buscando.

Dejar respuesta

Please enter your comment!
Please enter your name here