The previous article introduced the example of combining ASP. NET mvc3 and unity. Unity injects instances through the Register method or configuration, while MEF binds dependencies through the [import] [Export] feature. In MEF 2.0, if the type in the *. parts. * namespace of the current DLL is used as the dependency source. Compositionprovider. addpartsassembly can also be used to add dependency objects during runtime, which is flexible. The dependency defined by metadata and the dependency described by XML have their own advantages and disadvantages. The XML method will inevitably bring about the learning cost of configuration and maintenance (encoding injection is a way of writing, configuration is another way of writing), and the metadata definition method makes the relationship messy and scattered, and the intrusion is also strong.
The latest MEF 2.0 preview 5 has added system. componentmodel. Composition. Web. MVC. codeplex. DLL to simplify the creation of a flexible and testable ASP. net mvc application:
1) provide dependency injection for Controller
2) Identify and configure MEF parts (combinations) by defining simple conventions (Import & Export)
3) map the life cycle of the dependent instance to the life cycle of the request
4) Simplify the dependency injection Implementation of actionfilter and modelbinder
* Currently, the nuget method is not provided, so you can only download the DLL and manually add it:
1) system. componentmodel. Composition. codeplex. dll
2) system. componentmodel. Composition. Web. MVC. codeplex. dll
Let's take a look at the sample code. How can we use MEF to implement the IOC of ASP. net mvc?
Mvcwithmeftest is the MVC application, and controller IOC is the target. Genericrepository is the interface, and mvcwithmeftest. repository is the dependency to be injected.
(For the code of genericrepository and models, see my previous blog: [ASP. NET] ASP. net mvc 3 & unity. mvc3)
1. mvcwithmeftest. Export of repository
using System;using System.Collections.Generic;using GenericRepository;using MvcWithMefTest.Models;using System.ComponentModel.Composition;using System.Data.Entity;namespace MvcWithMefTest.Repository{ [Export(typeof(IRepository<User>))] public class UserRepository : DbContextRepository<User> { [ImportingConstructor] public UserRepository([Import("Database")]DbContext context) : base(context) { } } public class InjectDbInstance { [Export("Database")] public DbContext Database { get { return new DbEntities(); } } }}
The code above shows that the dbcontext instance is injected through the name-based importingconstructor. Is there any better way to inject constructor instances?
Although you can use compositionbatch. addexportedvalue to instantiate dbcontext injection in global. asax, you cannot get the compositioncontainer instance and cannot complete the final registration...
It seems necessary to study the implementation mechanism of compositionprovider.
2. irepository import in Controller
public class HomeController : Controller{ [Import] GenericRepository.IRepository<User> _userRepository; public ActionResult Index() { var users = _userRepository.GetAll(); return View(users); }}
3. Complete addpartsassembly in global. asax
protected void Application_Start(){ Database.SetInitializer(new MvcWithMefTest.Models.SampleData()); AreaRegistration.RegisterAllAreas(); RegisterGlobalFilters(GlobalFilters.Filters); RegisterRoutes(RouteTable.Routes); CompositionProvider.AddPartsAssembly(typeof(UserRepository).Assembly);}
Here addpartsassembly is implemented through typeof (XXX). assembly, and the actual physical separation can be completed through Assembly. loadfrom/LoadFile (that is, no repository. dll reference is added to the application project)