Injecting a Controller

ControllerFactory方法

一:使用Unity Inject a Controller

1, 引用Unity application block.

2, Adding a Unity Controller Factory

View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Microsoft.Practices.Unity;
using System.Web.Routing;

namespace Star.Web
{
    public class UnityControllerFactory : IControllerFactory
    {
        private IUnityContainer _container;
        private IControllerFactory _innerFactory;

        public UnityControllerFactory(IUnityContainer container)
            : this(container, new DefaultControllerFactory())
        {
        }

        protected UnityControllerFactory(IUnityContainer container, IControllerFactory innerFactory)
        {
            _container = container;
            _innerFactory = innerFactory;
        }

        public IController CreateController(RequestContext requestContext, string controllerName)
        {
            try
            {
                return _container.Resolve<IController>(controllerName);
            }
            catch (Exception)
            {
                return _innerFactory.CreateController(requestContext, controllerName);
            }
        }

        public void ReleaseController(IController controller)
        {
            _container.Teardown(controller);
        }

        public System.Web.SessionState.SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName)
        {
            return System.Web.SessionState.SessionStateBehavior.Default;
        }
    }
}

3, Registering Unity in Global.asax.cs

    Register a UnityControllerFactory of the previous container inside MVC ControllerBuilder as the current factory for the controllers:

View Code
var unity = new UnityContainer();
unity.RegisterInstance<HttpContextBase>(new HttpContextWrapper(HttpContext.Current) as HttpContextBase);    //注册子类为基类
unity.RegisterType<IWebHelper, WebHelper>();
unity.RegisterType<ILogger, NullLogger>();
unity.RegisterType<ICacheManager, NopNullCache>();
unity.RegisterType<IProductService, ProductService>();
unity.RegisterType<ICategoryService, CategoryService>();
unity.RegisterType<IPictureService, PictureService>();
unity.RegisterType<ISpecificationAttributeService, SpecificationAttributeService>();            
unity.RegisterType<IController, HomeController>("Home");
unity.RegisterType<IController, CatalogController>("Catalog");
            

/* 构造函数不带参数: unity.RegisterType<IDbContext, StarObjectContext>();   http://www.cnblogs.com/myaspnet/archive/2011/08/26/2154118.html
    构造函数带参数  : StarObjectContext的 */

unity.RegisterInstance<IDbContext>(new StarObjectContext("Data Source=69823-296-91609;Initial Catalog=XXX;uid=xx;pwd=xx"));
unity.RegisterType(typeof(IRepository<>), typeof(EfRepository<>));

var factory = new UnityControllerFactory(unity);
ControllerBuilder.Current.SetControllerFactory(factory);

来源:ASP.NET MVC 3 Dependency Injection

 

Dependency Resolver方法

Dependency Resolver: 依赖关系解析程序。

一:A Simple Dependency Resolver

1, 实现IDependencyResolver接口

The job of the dependency resolver is to create objects that the framework requires at run time, including controllers.
By providing a custom dependency resolver, you can create controller instances on behalf of the framework.

View Code
// A simple implementation of IDependencyResolver, for example purposes.
class SimpleContainer : IDependencyResolver
{
    static readonly IProductRepository respository = new ProductRepository();

    public IDependencyScope BeginScope()
    {
        // This example does not support child scopes, so we simply return 'this'.
        return this; 
    }

    public object GetService(Type serviceType)
    {
        if (serviceType == typeof(ProductsController))
        {
            return new ProductsController(respository);
        }
        else
        {
            return null;
        }
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        return new List<object>();
    }

    public void Dispose()
    {
        // When BeginScope returns 'this', the Dispose method must be a no-op.
    }
}

 2, Setting the Dependency Resolver

View Code
public class WebApiApplication : System.Web.HttpApplication
{
    void ConfigureApi(HttpConfiguration config)
    {
        config.DependencyResolver = new SimpleContainer();
    }

    protected void Application_Start()
    {
        ConfigureApi(GlobalConfiguration.Configuration);

        // ...
    }
}

 来源:Using the Web API Dependency Resolver

  

二:Dependency Injection with IoC Containers 

An IoC container is a software component that is responsible for creating dependencies. IoC containers provide a general framework for dependency injection.

View Code
namespace ProductStore 
{ 
    using System; 
    using System.Collections.Generic; 
    using System.Web.Http; 
    using System.Web.Http.Dependencies; 
    using Microsoft.Practices.Unity; 
 
    class ScopeContainer : IDependencyScope 
    { 
        protected IUnityContainer container; 
 
        public ScopeContainer(IUnityContainer container) 
        { 
            if (container == null) 
            { 
                throw new ArgumentNullException("container"); 
            } 
            this.container = container; 
        } 
 
        public object GetService(Type serviceType) 
        { 
            if (container.IsRegistered(serviceType)) 
            { 
                return container.Resolve(serviceType); 
            } 
            else 
            { 
                return null; 
            } 
        } 
 
        public IEnumerable<object> GetServices(Type serviceType) 
        { 
            if (container.IsRegistered(serviceType)) 
            { 
                return container.ResolveAll(serviceType); 
            } 
            else 
            { 
                return new List<object>(); 
            } 
        } 
 
        public void Dispose() 
        { 
            container.Dispose(); 
        } 
    } 
 
    class IoCContainer : ScopeContainer, IDependencyResolver 
    { 
        public IoCContainer(IUnityContainer container) 
            : base(container) 
        { 
        } 
 
        public IDependencyScope BeginScope() 
        { 
            var child = container.CreateChildContainer(); 
            return new ScopeContainer(child); 
        } 
    } 
}
View Code
void ConfigureApi(HttpConfiguration config) 
{ 
    var unity = new UnityContainer(); 
    unity.RegisterType<ProductsController>(); 
    unity.RegisterType<IProductRepository, ProductRepository>( 
        new HierarchicalLifetimeManager()); 
    config.DependencyResolver = new IoCContainer(unity); 
}

Notes: Inject a Controller不一定需要IoC,但是有IoC会让注入控制器更方便。

DependencyResolver vs. ControllerFactory

This is a "singly registered" style service introduced in MVC 1.0. The static registration point for this service is atControllerBuilder.Current.SetControllerFactory for non-DI users.

The logic in ControllerBuilder was updated to attempt to find IControllerFactory first by calling MvcServiceLocator.Current.GetInstance<IControllerFactory>(). If the service does not exist in the service locator, then it falls back to the static registration point. The default IControllerFactory remains DefaultControllerFactory.

 来源:http://bradwilson.typepad.com/blog/2010/07/service-location-pt2-controllers.html

 

If you make all your instances of your controllers available, for a standard app, it's highly unlikely that you would need a custom controller factory.

However, if you need to do something specific before, during or after the instantiation of your controller, you can use the controllerfactory to take care of these specific implementations before it is returned for use by the rest of the framework.

 来源:http://stackoverflow.com/questions/6810438/dependencyresolver-vs-controllerfactory

 

从 ControllerBuilder 的源码中,可以看出,如果没有注册 IControllerFactory,MVC 将自动使用 DefaultControllerFactory。

DefaultControllerFactory 在内部(DefaultControllerActivator 类)会尝试调用 DependencyResolver 来获取 Controller 的实例,如果不成功则使用 Activator.CreateInstance 。

来源:http://www.cnblogs.com/ldp615/archive/2011/08/16/asp-net-mvc-3-unity-dependency-resolver.html

原文地址:https://www.cnblogs.com/season2009/p/2733553.html