Asp.net MVC 通過自定義ControllerFactory實現構造器注入


一、重寫ControllerFactory的GetControllerInstance

ControllerFactory是asp.net中用於在運行時構造Controller的工廠 ,默認使用的工廠在構造Controller時,默認調用Controller的無參構造函數,所以要實現構造器注入,需要重寫工廠中構造Controller的方法GetControllerInstance:

 1 public class CustomControllerFactory : DefaultControllerFactory
 2     {
 3         protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext,Type controllerType)
 4         {
 5             //獲取構造函數對象
 6             var constructor = controllerType.GetConstructors()[0];
 7             //獲取構造函數參數
 8             var param = constructor.GetParameters();
 9             //獲取構造函數所需的參數
10             var paramNames = param.Select(a => {
11                 var serviceType = (ServiceAttribute)(a.ParameterType.GetCustomAttributes(typeof(ServiceAttribute), true)[0]);
12                 var t = Type.GetType(serviceType.ServiceName + ", " + serviceType.ServiceNameSpace, true);
13                 return Activator.CreateInstance(t);
14                 }).ToArray();
15             IController controller = Activator.CreateInstance(controllerType, paramNames) as Controller;
16             return controller;
17         }
18     }

 

在獲取構造函數參數的時候,需要讓發射機制尋找到服務的程序集,所以在這個地方我定義了一個名為Service的特性:

 1 public class ServiceAttribute : Attribute
 2     {
 3         private string _serviceName;
 4         private string _serviceNamespace;
 5         public ServiceAttribute(string serviceName, string serviceNamespace)
 6         {
 7             _serviceName = serviceName;
 8             _serviceNamespace = serviceNamespace;
 9         }
10 
11         public string ServiceName
12         {
13             get { return _serviceName; }
14         }
15 
16         public string ServiceNameSpace
17         {
18             get { return _serviceNamespace; }
19         }
20     }

 

二、定義服務接口:

1 [Service(serviceName: "InjectController.Service.Impl.AddService", serviceNamespace: "InjectController.Service.Impl")]
2 public interface IAddService
3 {
4     int Add(int a, int b);
5 }

 

serviceName是服務的全稱,serviceNamespace是服務的命名空間。

三、繼承服務接口並實現:

1     public class AddService:IAddService
2     {
3         public int Add(int a, int b)
4         {
5             return a + b;
6         }
7     }

 

四、在Controller中定義構造函數,引用服務接口

 1     public class HomeController : Controller
 2     {
 3         private ILoggerService _loggerService;
 4         private IAddService _addService;
 5         public HomeController(ILoggerService loggerService,IAddService addService)
 6         {
 7             _loggerService = loggerService;
 8             _addService = addService;
 9         }
10 
11         public ActionResult Index(int num1, int num2)
12         {
13             _loggerService.Logger(num1.ToString() + "+" + num2.ToString() + "=" + _addService.Add(num1,num2).ToString() + "    " + "\r\n");
14             return View("Index", new LoggerDTO() { LoggerContent = _loggerService.GetLogger() });
15         }
16     }

 


ILoggerService沒有在文章中列出,其格式與IAddService相同。

五、在Global.asax中重新注冊控制器工廠,覆蓋默認的構造器工廠:

 1     public class MvcApplication : System.Web.HttpApplication
 2     {
 3         protected void Application_Start()
 4         {
 5             AreaRegistration.RegisterAllAreas();
 6             FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
 7             RouteConfig.RegisterRoutes(RouteTable.Routes);
 8             BundleConfig.RegisterBundles(BundleTable.Bundles);
 9 
10             RegisterCustomControllerFactory();
11         }
12 
13         private void RegisterCustomControllerFactory()
14         {
15             IControllerFactory factory = new CustomControllerFactory();
16             ControllerBuilder.Current.SetControllerFactory(factory);
17         }
18     }

 

運行:發現接口成功的在構造函數中被注入


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM