How do I correctly use Unity to pass a ConnectionString to my repository classes?

后端 未结 4 1115
抹茶落季
抹茶落季 2020-12-08 07:49

I\'ve literally just started using the Unity Application Blocks Dependency Injection library from Microsoft, and I\'ve come unstuck.

This is my IoC class that\'ll ha

4条回答
  •  暗喜
    暗喜 (楼主)
    2020-12-08 08:38

    Probably the most straight forward way to do this is to set up a constructor section for your mapped type in the unity configuration and inside the constructor section have a parameter element for the connection string that passes in a name value for a connection string you have defined in the connectionStrings section of your web configuration.

    Inside your constructor code for the Repository class, have some code that uses the name value of the connection string to get the full connection string from the connectionStrings section.

    EDIT:

    Here's an example for you using Unity 2.0

    In your web.config, specify the connection string and a mapping for unity to map an IRepository to a SqlRepository. Based on your other questions, we'll assume that IRepository is in your model project and SqlRepository is in your DAL project.

    
    
        
            

    Now for the IRepository interface in the model project. In this example, I'm also going to be using LINQ to SQL to return objects from the SQL Database

    namespace ModelProject
    {
        /// 
        /// Interface implemented by a Repository to return
        ///  collections of objects
        /// 
        /// Object type to return
        public interface IRepository
        {
            IQueryable Items { get; }
        }
    }
    

    And the SQLRepository class in the DAL project

    namespace DALProject
    {
        /// 
        /// Generic class for returning an 
        /// collection of types
        /// 
        /// object type
        public class SqlRepository : IRepository where T : class
        {
            private Table _table;
    
            public SqlRepository(string connectionString)
            {
                // use the connectionString argument value to get the
                // connection string from the  section
                // in web.config
                string connection = ConfigurationManager.ConnectionStrings[connectionString].ConnectionString;
    
                _table = (new DataContext(connection)).GetTable();
            }
    
            /// 
            /// Gets an  collection of objects
            /// 
            public IQueryable Items
            {
                get { return _table; }
            }
        }
    }
    

    Let's also use a custom controller factory to allow unity to return controllers for us. This way, unity will inject any dependencies that the controllers have

    In global.asax

    namespace WebApplicationProject
    {
        public class MvcApplication : System.Web.HttpApplication
        {
            public static void RegisterRoutes(RouteCollection routes)
            {
                // your routes
            }
    
            protected void Application_Start()
            {
                RegisterRoutes(RouteTable.Routes);
                ControllerBuilder.Current.SetControllerFactory(new UnityControllerFactory());
            }
        }
    
        public class UnityControllerFactory : DefaultControllerFactory
        {
            private IUnityContainer _container;
    
            public UnityControllerFactory()
            {
                _container = new UnityContainer();
    
                var controllerTypes = from t in Assembly.GetExecutingAssembly().GetTypes()
                                      where typeof(IController).IsAssignableFrom(t)
                                      select t;
    
                foreach (Type t in controllerTypes)
                    _container.RegisterType(t, t.FullName);
    
                UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
    
                section.Configure(_container);
            }
    
            protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
            {
                // see http://stackoverflow.com/questions/1357485/asp-net-mvc2-preview-1-are-there-any-breaking-changes/1601706#1601706
                if (controllerType == null) { return null; }
    
                return (IController)_container.Resolve(controllerType);
            }
        }
    
    }
    

    And Here's a controller example. PageSize might be defined on a base controller or on the controller as a property.

    namespace WebApplicationProject.Controllers
    {
        public class CustomersController : Controller
        {
            private IRepository _customerRepository;
            public int PageSize { get; set; }
    
            public CustomersController() { }
    
            public CustomersController(IRepository customerRepository)
            {
                this._customerRepository = customerRepository;
                // let's set it to 10 items per page.
                this.PageSize = 10; 
            }
    
            public ViewResult List(string customerType, int page)
            {
                var customerByType = (customerType == null) ?
                    customerRepository.Items : customerRepository.Items.Where(x => x.CustomerType == customerType);
    
                int totalCustomers = customerByType.Count();
                ViewData["TotalPages"] = (int)Math.Ceiling((double)totalCustomers/ PageSize);
                ViewData["CurrentPage"] = page;
                ViewData["CustomerType"] = customerType;
    
                // get the right customers from the collection
                // based on page number and customer type.    
                return View(customerByType
                    .Skip((page - 1) * PageSize)
                    .Take(PageSize)
                    .ToList()
                );
            }
    
        }
    }
    

    When the customers list controller action is invoked, unity will correctly instantiate an instance of SqlRepository for the controller and inject this into the constructor. the connectionString string used for SqlRepository is set in the unity configuration and is passed into the constructor for a typed SqlRepository.

提交回复
热议问题