So you have a team of developers… And a nice architecture to build on… How about making that architecture easy for everyone and getting developers up to speed quickly? Learn all about integrating the managed extensibility framework (MEF) and ASP.NET MVC with some NuGet sauce for creating loosely coupled, easy to use architectures that anyone can grasp.
2. www.realdolmen.com
FUN WITH ASP.NET MVC 3,
MEF AND NUGET
DECEMBER 12, 2011 | SLIDE 2
3. WHO AM I?
Maarten Balliauw
Antwerp, Belgium
Me, looking
www.realdolmen.com intelligent with
Focus on web glasses
ASP.NET MVC, PHP, Azure, SignalR, …
MVP Windows Azure (formerly ASP.NET)
Co-founder of AZUG
http://blog.maartenballiauw.be
@maartenballiauw
DECEMBER 12, 2011 | SLIDE 4
4. AGENDA
Technologies & techniques used
ASP.NET MVC 3
Managed Extensibility Framework (MEF)
NuGet
Creating application components
Building an application
Conclusion
Further information
Q&A
DECEMBER 12, 2011 | SLIDE 5
5. ASP.NET MVC 3
All the new stuff:
Razor view engine
Global Action Filters
Unobtrusive Ajax & Client Validation
Better Visual Studio tooling
And a very interesting one for doing LEGO
development:
Better support for Dependency Injection
DECEMBER 12, 2011 | SLIDE 6
6. DEPENDENCY INJECTION?
I need a
var partA =
“Part B” ! new PartA(new PartB())
Coming
up!
Me on a
typical
work day
DECEMBER 12, 2011 | SLIDE 7
7. DEPENDENCY INJECTION?
I need a
Let me
There
“Part B” !
you go!
see...
Container
DECEMBER 12, 2011 | SLIDE 8
8. WHAT ABOUT ASP.NET MVC 3?
ASP.NET MVC 3 uses DependencyResolver
: IDependencyResolver
GetService()
GetServices()
Register it on application start
DECEMBER 12, 2011 | SLIDE 9
9. WHAT ABOUT ASP.NET MVC 3?
ASP.NET MVC will / can query the
IDependencyResolver for
Controllers Value providers
View engines & view pages Model binders
Filters Controller activator
Model validators View page activator
Model metadata
Check Brad Wilson’s blog for examples on all of
these
http://bradwilson.typepad.com/blog/2010/07/service-
location-pt1-introduction.html
DECEMBER 12, 2011 | SLIDE 10
10. in ASP.NET MVC 3
DEPENDENCY INJECTION
DECEMBER 12, 2011 | SLIDE 11
11. MANAGED EXTENSIBILITY
FRAMEWORK (MEF)
Cool as ICE: Import, Compose, Export
[Import]IRule rule;
MEF catalog
[Export(typeof(IRule)]
Let me
There
you go!
see...
DECEMBER 12, 2011 | SLIDE 12
12. MEF IN ASP.NET MVC 3
Build an IDependencyResolver
based on MEF container
Use
has a built-in IDependencyResolver
has a “Convention” model
is available on NuGet
mefcontrib.codeplex.com
DECEMBER 12, 2011 | SLIDE 13
13. NUGET
“NuGet is a Visual Studio extension that makes it easy to install
and update open source libraries and tools in Visual Studio.”
Publish your own packages
+ Create & use your own feed
DECEMBER 12, 2011 | SLIDE 14
14. and finding it on NuGet
USING MEFCONTRIB
DECEMBER 12, 2011 | SLIDE 15
15. MEFCONTRIB.MVC3
Optional addition for
Adds some things to your application:
AppStart code that does the wiring
A CompositionDependencyResolver
Will check all assemblies in /bin
Will export everything : IController by convention
DECEMBER 12, 2011 | SLIDE 16
16. CONVENTIONS BASED MODEL
public class MvcApplicationRegistry : PartRegistry {
public MvcApplicationRegistry() {
Scan(x => {
x.Assembly(Assembly.GetExecutingAssembly());
x.Directory(AppDomain.CurrentDomain.BaseDirectory + "bin");
});
Part()
.ForTypesAssignableFrom<IController>()
.MakeNonShared()
.ExportTypeAs<IController>()
.ExportType()
.Imports(
// ...
);
}
}
DECEMBER 12, 2011 | SLIDE 17
17. THIS ALL MAKES ME THINK...
Package company components using
NuGet?
Distribute them in a custom feed?
Use ASP.NET MVC 3?
Wire everything with MEF & MefContrib?
Pure application Lego!
Me, thinking
DECEMBER 12, 2011 | SLIDE 18
19. WHAT’S NEXT?
Building it
MSBuild (or whatever! Nuget.exe is all that matters)
Hosting it Install-Package NuGet.Server
Create a NuGet server
Drop everything in a folder
Use a NaaS solution: www.myget.org
Using it
Reference the feed
Download & install components needed
Assemble using MEF (or another IoC)
DECEMBER 12, 2011 | SLIDE 20
20. A QUICK COMMERCIAL PLUG
Create your own NuGet feed
Packages from official feed
Uploaded/pushed packages
No need to setup & maintain your own NuGet Server
Free! www.myget.org
DECEMBER 12, 2011 | SLIDE 21
22. LET’S SEE IF WE CAN BUILD THIS...
TPS Reports Cover Sheet Generator
(ASP.NET MVC 3) Wired
Domain layer Authentication Theme
with MEF
Domain.TpsReports AccountController Default theme
Contracts
Packaged
as .nupkg
And their
implementations...
DECEMBER 12, 2011 | SLIDE 23
24. CONCLUSION
You can build an app like a Lego set
Requires “bricks” (NuGet packages)
Requires “glue” (MEF / MefContrib / IoC)
Requires you to think in terms of components
Structure is key!
Not a best-practice architecture
Just something we toyed with on a project
Proved to work (for the customer)
DECEMBER 12, 2011 | SLIDE 25
25. FURTHER INFORMATION
On the Internet:
www.nuget.org
www.myget.org
mefcontrib.codeplex.com
DECEMBER 12, 2011 | SLIDE 26
26. THANK YOU FOR JOINING
Me, having
a question
DECEMBER 12, 2011 | SLIDE 27
Notes de l'éditeur
Demo01_MVC_DependencyResolverAdd a property to the HomeController for specifying the welcome messageAdd a class “SimpleDependencyResolver.cs”Implement IdependencyResolver (use snippets for some parts) public class SimpleDependencyResolver : IDependencyResolver { public object GetService(Type serviceType) { if (serviceType == typeof(Controllers.HomeController)) { var controller = Activator.CreateInstance(serviceType) as Controllers.HomeController; controller.MessageText = "Welcome, this text has been injected!"; return controller; } if (serviceType.IsInterface) { if (serviceType == typeof(IControllerFactory)) return new DefaultControllerFactory(); if (serviceType == typeof(IControllerActivator)) return null; if (serviceType == typeof(IFilterProvider)) return GlobalFilters.Filters; if (serviceType == typeof(IViewEngine)) return new RazorViewEngine(); if (serviceType == typeof(IViewPageActivator)) return null; } return Activator.CreateInstance(serviceType); } public IEnumerable<object> GetServices(Type serviceType) { return new object[] { GetService(serviceType) }; } } Register dependencyresolver in App_Start:DependencyResolver.SetResolver(new SimpleDependencyResolver());
Maarten
Demo02_MefContribCreate a new MVC application (application template)Add an IHelloWorldService public interface IHelloWorldService { string Hello(); } Add a HelloWorldService [Export(typeof(IHelloWorldService))] public class HelloWorldService : IHelloWorldService { public string Hello() { return "Hello from HelloWorldService!"; } } Change HomeController public class HomeController : Controller { private IHelloWorldService service; [ImportingConstructor] public HomeController(IHelloWorldService helloWorldService) { this.service = helloWorldService; } public ActionResult Index() { ViewBag.Message = this.service.Hello(); return View(); } public ActionResult About() { return View(); } } Run and fail…NuGet the MefContrib.MVC packageExplain the fact that it uses the /bin folder for part discoveryExplain the use of conventions
Initech.Components.Theming.DefaultThemeOpen solutionShow it’s nothing but a “plain old” MVC applicationRun the projectDemonstrate it does nothing, it’s just a template…Show the NuGet folder in Windows ExplorerOpen package.nuspec using NuGet Package ExplorerShow people around:Show the “Content” folder, this is where package contents will go. In this case, it will contain the Views, CSS and scripts.Show “lib”: it will contain assemblies (if appropriate for the package)Package.proj is the MSBUILD script that does the packagingOpen itSpecify some settings about what to copy and packageUpdate version number in nuspec fileRun nuget.exe on the nuspec fileAwesomeness!
Tonen aparte directoryTonen NuGet.ServerTonen MyGet.org
IniTech.TpsCoverSheetGeneratorCreate an empty MVC applicationAdd a library package reference to InitechThemeDefaultThemeUpdate _ViewStart.cshtml to use _InitechLayout.cshtmlAdd a HomeControllerAdd a viewRun the application to show off the templateRemove the view: we’ll generate that later onAdd library package reference (from command line?) to InitechDomainTpsReportsModify Index() action method: public ActionResult Index() { return View(new TpsReportCoverSheet()); } Add POST action [HttpPost] public ActionResult Index(TpsReportCoverSheet model) { if (ModelState.IsValid) { return View("TpsReportCoverSheet", model); } return View(model); } Add [Authorize] attributeAdd library package reference to InitechWebMvcAuthenticationDemonstrate it adds dependencies from NuGet as well as from Initech package repositoryWe need an implementation for the contracts… InitechAuthenticationMembershipDummy & InitechAuthenticationFormsShow the app: almost no code, we just combined some building blocks…