I am a newbie to MEF and I am really mixed up! There are lot of useful articles out there and neat question and answers here in stackoverflow. I downloaded the example which @matthew-abbott has uploaded in his blog , but I dont know how to add new plug-ins or extension to extend the main web application, I mean like what you can see here.
Edited : Also I use Entity Framework, Code First Approach and Unit of work for my data access layer application, what If my plug-ins needs data access and (I mean the plug-in has itself models) wants to use the DAL I created ? As you know every time the model changes, DbContext throws and error and tells re-create DB, Is there any way or other ORM which accept开发者_Go百科s extending DAL dynamically?
That particular example shows how we can integrate MEF with MVC3's new DependencyResolver
which provides a service location mechanism for various extension points within the MVC architecture. There are a few other articles on my blog which detail more information about how a possible plugin architecture could work, these are available at:
- Modular ASP.NET MVC using the Managed Extensibility Framework (MEF), Part One
- Modular ASP.NET MVC using the Managed Extensibility Framework (MEF), Part Two
- Modular ASP.NET MVC using the Managed Extensibility Framework (MEF), Part Three
There are also a host of fantastic articles, my recommendations would be to also read:
- ASP.NET MVC and the Managed Extensibility Framework (MEF) by Maarten Balliauw
- Defining Web-scoped parts with MEF by Tim Roberts
MVC is a very flexible architecture, there are a myriad of ways it can be extended, but because of the nature of how ASP.NET applications run in IIS, you need to consider part lifetime very carefully. As an example, controllers can only be used for one request, so you could would need to ensure that your controllers have a specific CreationPolicy
. Tim Robert's article on Web-scoped parts is a particularly good read.
Hope that is enough to point you in the right direction.
Edit: Because of the modular nature that MEF provides, it is important to ensure that your different layers are decoupled. You've specified that you are using Entity Framework, but the reality is, EF should likely only be used in your data layer. Typically the MVC architecture would promote view models over domain models. To that end, it is probably useful to use something similar to the repository pattern to define, e.g. here is a mock UserRepository
:
[Export(typeof(IUserRepository))]
public class UserRepository : IUserRepository
{
public IEnumerable<UserViewModel> GetUsers()
{
// Get values here from EF as domain models
// And return them as view models?
}
}
Which we can export and inject into a controller:
[ExportController("User"), PartCreationPolicy(CreationPolicy.NonShared)]
public class UserController : Controller
{
private readonly IUserRepository _repo;
[ImportingConstructor]
public UserController(IUserRepository repo)
{
if (repo == null)
throw new ArgumentNullException("repo");
_repo = repo;
}
public ActionResult Index()
{
var users = _repo.GetUsers();
return View(users);
}
}
This is just a really simple example, but like many IoC containers, MEF also supports dependency injection. As long as a part provides a suitable export, it can be imported (either through property injection, or constructor injection) into another part at composition time.
My recommendation would be against exposing EF to your views, as this makes them explicitly dependent on it. By taking care to decouple and only expose the right types at the right layers, you architecture will become a lot more robust, flexible and testable, which makes maintaining it, and updating it a lot easier. As another quick example, here is how we could test our controller:
[Test]
public void UserController_CreatesViewResult_WithListOfUsers()
{
var mock = new Mock<IUserRepository>();
mock.Setup(m => m.GetUsers()).Returns(new[] { new UserViewModel { Name = "Matt" } });
var controller = new UserController(mock.Object);
var result = controller.Index();
Assert.That(result is ViewResult);
// Other assertions.
}
Because I haven't tightly coupled EF to my view, my controller is a lot more testable, I can mock a suitable repository and test where I need to.
The important thing is planning your architecture.
精彩评论