none
IoC in a Class Library RRS feed

  • Question

  • I am building a c# dll class library which may be used across different solutions.  I want to use SOLID principles including a dependency injection container, but I don't know how to get started.  I have questions like: 2) Can I use IoC in a dll?, 2) Can a DI container, like Autofac, be used in a dll project?, 3)  If so, where is the entry point in the dll where I would put a container builder?, 4)..., etc. 

    In which forum should I ask my questions?


    Rob E.

    Monday, October 23, 2017 4:20 PM

Answers

  • Thank you, for the example.  I am a bit more familiar with WPF rather than MVC so your example is a bit esoteric from my perspective.

    It doesn't make any difference if it is ASP.NET MVC, ASP.NET Web form, WPF, Console Application, Windows form or whatever, the IoC container is defined at the highest level, the root project, and it would have reference to all classlib projects where you expect the objects in the classlib project to be DI-ed into another class/object with all objects instanced in the IoC.

    Other IoC's allow the classlib to be defined only and all classes/objects in the classlib are instanced and put into the IoC container, but I can't recall what the terminology is called for it, which Castle Windsor and other IoC(s) have the technology. 

    The IoC would be defined and initiated at  App_Startup, WPF has this, just like ASP.NET MVC solution has a Application_Start() executed by the Global.asax,  the Program.cs has a startup logic, etc, etc in Windows form,  Console Application or OnStart() with Windows service etc., etc.

    using System.IO;
    using System.Web.Mvc;
    using System.Web.Optimization;
    using System.Web.Routing;
    using MVC.App_Start;
    
    namespace MVC
    {
        public class MvcApplication : System.Web.HttpApplication
        {
            protected void Application_Start()
            {
                AreaRegistration.RegisterAllAreas();
                UnityMVC5.Start();
                FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
                RouteConfig.RegisterRoutes(RouteTable.Routes);
                BundleConfig.RegisterBundles(BundleTable.Bundles);
                log4net.Config.XmlConfigurator.Configure(new FileInfo(Server.MapPath("~/Web.config")));
            }
        }
    }
    

    Are you saying that the application that references the dll must have knowledge of which container, e.g. Unity, is used in the dll?

    No, and no classlib project that I have seen knows about the IoC if you are doing the application infrastructure the way I have seen it done when an IoC is being used in the solution. The IoC and dependency injection of a class/object into another class/object is paramount unit testing the solution. 

      If so, I might be better off attempting to dependency injection without a container.  Also, I would still need to know where to locate the container builder in the dll.

    I have never heard or seen this, and I have used 3 different IoC(s) in doing unit testing of solutions including those that use classlib projects in enterprise level Web and non Web based solutions.

    Below is where I use Unity on the other side of the WCF service to instance objects in the Repository and the DAL with DAL using Data Access Objects when the Repository and DAL are used by the WCF service. The MVC solution can't see past the Web service to  instance objects in its Unity container sitting on the MVC side of the solution.

    Every time the WCF service is called by the client on the client's own thread, the needed objects are instanced in the IoC container for the client instance of using WCF.

    using Microsoft.Practices.Unity;
    using Unity.Wcf;
    using WcfService;
    using Repository;
    using DAL.DAO;
    
    namespace WCFSrvcFactory
    {
    	public class WcfServiceFactory : UnityServiceHostFactory
        {
            protected override void ConfigureContainer(IUnityContainer container)
            {
    			// register all your components with the container here
                container
                    .RegisterType<IService1, Service1>()
                    .RegisterType<IStudentRepo, StudentRepo>()
                    .RegisterType<IEnrollmentRepo, EnrollmentRepo>()
                    .RegisterType<IDAOStudent, DAOStudent>()
                    .RegisterType<IDAOCourse, DAOCourse>()
                    .RegisterType<IDAOEnrollment, DAOEnrollment>();
            }
        }    
    }

       
    • Marked as answer by REvans611 Tuesday, October 24, 2017 12:18 AM
    Monday, October 23, 2017 11:11 PM

All replies

  • Can I use IoC in a dll?

    Yes it can,  but the solution that has reference to the DLL will defined the IoC container by using the Interface that defines the DLL contract and the location of the DLL.

    using System.Data;
    using System.Data.Common;
    using System.Web;
    using System.Web.Mvc;
    using Microsoft.AspNet.Identity;
    using Microsoft.AspNet.Identity.EntityFramework;
    using Microsoft.Owin.Security;
    using Microsoft.Practices.Unity;
    using Unity.Mvc5;
    using ServiceLayer;
    using WebAPI.Controllers;
    using MVC.Models;
    
    namespace MVC.App_Start
    {
        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());
            }
        }
    
        public class UnityMVC5
        {
            public static void Start()
            {
                var container = BuildUnityContainer();
                DependencyResolver.SetResolver(new UnityDependencyResolver(container));
            }
    
            private static IUnityContainer BuildUnityContainer()
            {
                var container = new UnityContainer();
    
                //Models
                container.BindInRequestScope<IStudentModels, StudentModels>();
                container.BindInRequestScope<IEnrollmentModels, EnrollmentModels>();
    
                //SeviceLayer
                container.BindInRequestScope<IServiceA, ServiceA>();
    
                //WebAPI controllers
                container.BindInRequestScope<IStudentControllerAPI, StudentController>();
                container.BindInRequestScope<IEnrollmentControllerAPI, EnrollmentController>();
    
                //asp.net idenity
    
                container.RegisterType<ApplicationDbContext>();
                container.RegisterType<ApplicationSignInManager>();
                container.RegisterType<ApplicationUserManager>();
                container.RegisterType<IAuthenticationManager>(
                                 new InjectionFactory(c => HttpContext.Current.GetOwinContext().Authentication));
                container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>(
                            new InjectionConstructor(typeof(ApplicationDbContext)));
    
                return container;
            }
        }
    }

    The IoC container holds an instance of the object in the container,  and an object is dependency injected into a object/class defined in the DLL. You can use property of constructor injection of an object into class/object in the classlib project.

    using System.Collections.Generic;
    using System.Web.Http;
    using Entities;
    using Helper.Enums;
    using ServiceLayer;
    
    namespace WebAPI.Controllers
    {
        public class StudentController : ApiController, IStudentControllerAPI
        {
            private IServiceA srv;
            public StudentController(IServiceA service)
            {
                srv = service;
            }
    
            [HttpGet]
            public List<DTOStudent> GetStudents()
            {
                var dtos = srv.GetStudents();
    
                return dtos;
            }
    
            [HttpGet]
            public DTOStudent GetStudentById(int id)
            {
                return srv.GetStudentById(id);
            }
    
            [HttpPost]
            public void CreateStudent(DTOStudent dto)
            {
                srv.CreateStudent(dto);
            }
    
            [HttpPost]
            public void UpdateStudent(DTOStudent dto)
            {
                srv.UpdateStudent(dto);
            }
    
            [HttpPost]
            public void DeleteStudent(int id)
            {
                srv.DeleteStudent(id);
            }
    
            [HttpGet]
            public bool IsStudentAuthorised(ResourceTypeEnum resourceType, object resourceId, string username)
            {
                return Models.Helper.IsStudentAuthorised(resourceType, resourceId, username, srv);
            }
        }
    }
    
       

    Can a DI container, like Autofac, be used in a dll project?, 3)  If so, where is the entry point in the dll where I would put a container builder?, 4)..., etc. 

    All the IoC(s) pretty much work the same way as you see Unity being used in the example code.

    Monday, October 23, 2017 7:13 PM
  • Can I use IoC in a dll?

    Yes it can,  but the solution that has reference to the DLL will defined the IoC container by using the Interface that defines the DLL contract and the location of the DLL.

    Thank you, for the example.  I am a bit more familiar with WPF rather than MVC so your example is a bit esoteric from my perspective.

    Are you saying that the application that references the dll must have knowledge of which container, e.g. Unity, is used in the dll?  If so, I might be better off attempting to dependency injection without a container.  Also, I would still need to know where to locate the container builder in the dll.


    Rob E.

    Monday, October 23, 2017 9:41 PM
  • Thank you, for the example.  I am a bit more familiar with WPF rather than MVC so your example is a bit esoteric from my perspective.

    It doesn't make any difference if it is ASP.NET MVC, ASP.NET Web form, WPF, Console Application, Windows form or whatever, the IoC container is defined at the highest level, the root project, and it would have reference to all classlib projects where you expect the objects in the classlib project to be DI-ed into another class/object with all objects instanced in the IoC.

    Other IoC's allow the classlib to be defined only and all classes/objects in the classlib are instanced and put into the IoC container, but I can't recall what the terminology is called for it, which Castle Windsor and other IoC(s) have the technology. 

    The IoC would be defined and initiated at  App_Startup, WPF has this, just like ASP.NET MVC solution has a Application_Start() executed by the Global.asax,  the Program.cs has a startup logic, etc, etc in Windows form,  Console Application or OnStart() with Windows service etc., etc.

    using System.IO;
    using System.Web.Mvc;
    using System.Web.Optimization;
    using System.Web.Routing;
    using MVC.App_Start;
    
    namespace MVC
    {
        public class MvcApplication : System.Web.HttpApplication
        {
            protected void Application_Start()
            {
                AreaRegistration.RegisterAllAreas();
                UnityMVC5.Start();
                FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
                RouteConfig.RegisterRoutes(RouteTable.Routes);
                BundleConfig.RegisterBundles(BundleTable.Bundles);
                log4net.Config.XmlConfigurator.Configure(new FileInfo(Server.MapPath("~/Web.config")));
            }
        }
    }
    

    Are you saying that the application that references the dll must have knowledge of which container, e.g. Unity, is used in the dll?

    No, and no classlib project that I have seen knows about the IoC if you are doing the application infrastructure the way I have seen it done when an IoC is being used in the solution. The IoC and dependency injection of a class/object into another class/object is paramount unit testing the solution. 

      If so, I might be better off attempting to dependency injection without a container.  Also, I would still need to know where to locate the container builder in the dll.

    I have never heard or seen this, and I have used 3 different IoC(s) in doing unit testing of solutions including those that use classlib projects in enterprise level Web and non Web based solutions.

    Below is where I use Unity on the other side of the WCF service to instance objects in the Repository and the DAL with DAL using Data Access Objects when the Repository and DAL are used by the WCF service. The MVC solution can't see past the Web service to  instance objects in its Unity container sitting on the MVC side of the solution.

    Every time the WCF service is called by the client on the client's own thread, the needed objects are instanced in the IoC container for the client instance of using WCF.

    using Microsoft.Practices.Unity;
    using Unity.Wcf;
    using WcfService;
    using Repository;
    using DAL.DAO;
    
    namespace WCFSrvcFactory
    {
    	public class WcfServiceFactory : UnityServiceHostFactory
        {
            protected override void ConfigureContainer(IUnityContainer container)
            {
    			// register all your components with the container here
                container
                    .RegisterType<IService1, Service1>()
                    .RegisterType<IStudentRepo, StudentRepo>()
                    .RegisterType<IEnrollmentRepo, EnrollmentRepo>()
                    .RegisterType<IDAOStudent, DAOStudent>()
                    .RegisterType<IDAOCourse, DAOCourse>()
                    .RegisterType<IDAOEnrollment, DAOEnrollment>();
            }
        }    
    }

       
    • Marked as answer by REvans611 Tuesday, October 24, 2017 12:18 AM
    Monday, October 23, 2017 11:11 PM
  • So I think I have the gist of what you are saying.  My dll, which I hoped to be used with different solutions, can use a DI container only if its container, e.g., Unity of Autofac, is of the same type as the root applications that will use the dll.  So if I have no control over which applications will be using the library, I need to forgo the use of a DI container;  unless IoC can be done in an agnostic manner.   

    "If so, I might be better off attempting to dependency injection without a container. "

    The following link discusses such an attempt at an "agnostic" DI.  Answer number 35 on that page leads me to think DI can be done in such a manner, but I was hoping to do it with Autofac.

    Dependency Inject (DI) “friendly” library

    Thank you, for your help.


    Rob E.

    Tuesday, October 24, 2017 12:18 AM