I am really just starting out with MVVM, IoC and Dependency Injection and I've hit a stumbling block that I don't know how to solve but I do understand why it's happening.
I am using Castle Windsor for DI and IoC functionality and MVVM Light as my MVVM framework in a WPF application. Using this tutorial I have managed to get Castle Windsor to create a MainPageViewModel that has a IGroupRepository injected into the constructor. I have registered a mock implementation of this in Castle Windsor.
The following is the only other code in the MainPageViewModel class besides the constructor.
public ObservableCollection<GroupViewModel> Groups
{
get
{
var groupVms = new ObservableCollection<GroupViewModel>();
IEnumerable<Group> groups = _repository.GetAllGroups();
foreach (Group g in groups)
{
var vm = new GroupViewModel(g);
groupVms.Add(vm);
}
return groupVms;
}
}
The intention is to create a view model for each of the groups in the repository. However, doing this causes Castle Windsor to give the following exception:
Can't create component 'Planner.ViewModel.GroupViewModel' as it has dependencies
to be satisfied.
'Planner.ViewModel.GroupViewModel' is waiting for the following dependencies:
Service 'Planner.Models.Group' which was not registered.
I understand this exception - Castle Windsor is responsible for constructing my view models but it has no way of handling my entity.
I have done plenty of Googling but have found very few answers or suggestions to this problem which makes me think that what I am doing is wrong. This Stack Overflow question has two answers which suggest that having an entity on the view model is ok but I'm beginning to wonder if that's true. Other questions, such as this one suggest that the entity should be nowhere near the view model.
What is the correct way to resolve this problem?
Update: As requested, this is the stacktrace for the exception:
at Castle.MicroKernel.Handlers.DefaultHandler.AssertNotWaitingForDependency()
at Castle.MicroKernel.Handlers.DefaultHandler.ResolveCore(CreationContext context, Boolean requiresDecommission, Boolean instanceRequired, Burden& burden)
at Castle.MicroKernel.Handlers.DefaultHandler.Resolve(CreationContext context, Boolean instanceRequired)
at Castle.MicroKernel.Handlers.AbstractHandler.Resolve(CreationContext context)
at Castle.MicroKernel.DefaultKernel.ResolveComponent(IHandler handler, Type service, IDictionary additionalArguments, IReleasePolicy policy)
at Castle.MicroKernel.DefaultKernel.Castle.MicroKernel.IKernelInternal.Resolve(Type service, IDictionary arguments, IReleasePolicy policy)
at Castle.MicroKernel.DefaultKernel.Resolve(Type service, IDictionary arguments)
at Castle.Windsor.WindsorContainer.Resolve(Type service)
at Planner.ViewModel.ViewModelResolver.Resolve(String viewModelName) in D:\Planner\Planner\Planner\ViewModel\ViewModelResolver.cs:line 27
at Planner.ViewModel.ViewModelLocator.get_Item(String viewModelName) in D:\Planner\Planner\Planner\ViewModel\ViewModelLocator.cs:line 21
I thought that this was the correct behaviour because of the following code which (I believe) intercepts any calls to the constructor of a view model and injects them as appropriate.
public class ViewModelResolver : IViewModelResolver
{
private IWindsorContainer _container;
public object Resolve(string viewModelName)
{
if (_container == null)
{
_container = new WindsorContainer();
_container.Install(new WindsorViewsInstaller());
_container.Install(new WindsorRepositoriesInstaller());
}
var viewModelType =
GetType()
.Assembly
.GetTypes()
.Where(t => t.Name.Equals(viewModelName))
.FirstOrDefault();
return _container.Resolve(viewModelType);
}
}
Update 2: I think this answers Ritch's query:
public class ViewModelLocator : DynamicObject
{
public IViewModelResolver Resolver { get; set; }
public ViewModelLocator()
{
Resolver = new ViewModelResolver();
}
public object this[string viewModelName]
{
get
{
return Resolver.Resolve(viewModelName);
}
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = this[binder.Name];
return true;
}
}
I think I understand this a little more now. The problem isn't actually with the original code I posted. The problem is occurring actually setting up Windsor isn't it? I'm still not sure how I solve that problem though.
The property Groups on MainPageViewModel creates a bunch of VMs that aren't in the container, but your stacktrace is the Locator looking to bind/create an instance of the GroupViewModel (Why? I cannot tell at this point with the code you've posted.).
You have a disconnect in how the GroupViewModels are created and what the container is doing. You either need to let Windsor create these through a factory interface Factory Interface Documentation or remove them from the container entirely and manage them yourself. Based on gut feeling, I would lean towards the factory interface.
Ritch's answer led me in the right direction but I wanted to post a separate answer so that I can show the code that I ended up with in the hope that it will be useful to the next person trying to do this.
As well as Ritch's answer, this Stack Overflow question and this blog post by one of the main contributers to Castle Windsor, Krzysztof Koźmic, all helped me to solve this problem in what I believe is the correct way.
As Ritch said, I shouldn't have been calling the constructor for my view model directly - that is what the container is there for. So the way to do it is to create a class which will help Windsor to create your view model. This is known as a typed factory facility. The good thing about these classes is that you don't actually need to implement them - they are just interfaces. This is the code for the class that will eventually be used to create the view model:
public interface IGroupViewModelFactory
{
GroupViewModel Create(Group group);
}
This is injected into the constructor for the view model that will create the GroupViewModel which in my case was the MainWindowViewModel class. Here is the code for that class:
public class MainWindowViewModel : ViewModelBase
{
private readonly IGroupRepository _repository;
private readonly IGroupViewModelFactory _groupViewModelFactory;
public MainWindowViewModel(IGroupRepository repository, IGroupViewModelFactory groupViewModelFactory)
{
_repository = repository;
_groupViewModelFactory = groupViewModelFactory;
}
public ObservableCollection<GroupViewModel> Groups
{
get
{
var groupVms = new ObservableCollection<GroupViewModel>();
IEnumerable<Group> groups = _repository.GetAllGroups();
foreach (Group g in groups)
{
var vm = _groupViewModelFactory.Create(g);
groupVms.Add(vm);
}
return groupVms;
}
}
}
The final step is to register the factory class with Windsor and that is done by this piece of code:
_container.AddFacility<TypedFactoryFacility>();
_container.Register(
Component.For<Group>(),
Component.For<IGroupViewModelFactory>()
.AsFactory());
It's worth noting that the question I linked to earlier did not have the Component.For<Group>(), line in the above piece of code. Without that I was getting an exception from Windsor but unfortunately I didn't keep the details and I can no longer replicate it so there was probably something else amiss in my application.
Through the magic of Castle Windsor, you can now create view models from entities in a repository!
Related
Okay so I am looking for some specific tips about Dependency Injection and how to use it.
Basically I have a MVC website which uses Ninject (and the Ninject MVC package). So when I am creating the MVC page I use constructor injection in the controllers. This is okay but IMO a bit 'ugly', but the main thing I don't like is having to pass all of the injected repositories into the other classes, it just seems a bit OTT having to pass like 6 repositories-8 repositories into a static method or object constructor.
Not to mention that on some of my pages I am having to work on almost every repository so the controller consructor gets huge and not the most manageable.
Are there any other options that wont clutter my code up as much? I don't really want to pass them in as single 'setting' objects either as that just moves the problem to a different line of code.
I also use the same class libraries for console/desktop applications. I like the idea of using DependencyResolver.Current in the class libraries but everyone says this is an anti-pattern and constructor injection should be used.
Maybe have an MyProjectDIContext class which has a dictionary which i can populate with the injected types in the controller constructors then pass the context to all methods as needed?
I have had a look for the answer bit I can't quite seem to find something that fits well.
One of the great things about Constructor Injection is that it makes design and maintainability problems more obvious. When using constructor injection, it becomes very easy to see the amount of dependencies a class has, whereas without constructor injection, a class still has the same number of dependencies, but they are tucked away.
The problem you are seeing is called Constructor Over-injection and it's a design smell, because it indicates that you are violating the Single Responsibility Principle (SRP). The SRP guides in keeping your classes small, focussed and most of all: maintainable.
Are there any other options that wont clutter my code up as much?
Absolutely: make smaller classes. MVC controllers typically get huge when we use it to group methods of a certain concept, such as 'customer' or 'order'. This however means that a controller is an ever growing class that has to be changed for any new feature that arrives. This is a violation of the Open/closed Principle that tells we should strive to have a system where we can plugin new features without having to touch existing classes.
The solution therefore is not to revert to the Service Locator anti-pattern or Property Injection, but to create smaller classes that do one particular thing. Constructor Injection should be your primary way of applying Dependency Injection, even in class libraries.
It seems that your controller is shuffling repositories to other classes. Let Ninject supply those classes to you instead:
public class Controller
{
public Controller(IDependencyFactory dependency) { }
}
public interface IDependencyFactory
{
IDependency CreateDependency();
}
public interface IDependency
{
}
public class Dependency : IDependency
{
public Dependency() { }
}
public class Program
{
public static void Main()
{
var standardKernel = new StandardKernel();
standardKernel.Bind<IDependencyFactory>().ToFactory();
standardKernel.Bind<IDependency>().To<Dependency>();
}
}
You don't have to write an implementation of IDependencyFactory, that is handled by the factory extension. Your Dependency-class will get it's dependencies injected by Ninject.
Okay I seem to have found a way to do this which doesn't seem as smelly!
I had thought that if you are for example using MVC you would get the Repositories in through the constructor and that was the only way to resolve the dependencies.
After doing some work to move sections of reusuable code into IoC friendly Interfaces and their implementations I noticed that when you create reference IMyInterface in a controller constructor the default constructor of the implementing class is run and you can pull other IoC classes such as resolved repositories from there.
This may be common knowledge but it does make things much much neater and solves the problem I was having.
Example
Controller
public IDefaultTemplateManager DefaultTemplateManager { get; set; }
public DefaultController(IDefaultTemplateManager defaultTemplateManager) {
this.DefaultTemplateManager = defaultTemplateManager;
}
public ActionResult MyAction(FormCollection collection) {
DefaultTemplateManager.Process("MyKeyHere");
View();
}
IDefaultTemplateManager
public interface IDefaultTemplateManager {
ProcessResponse Process(string UniqueKey, DefaultTemplateManagerEditMode DatabaseName, string DefaultTemplateName);
}
DefaultTemplateManager
public class DefaultTemplateManager : IDefaultTemplateManager {
protected IRepository<MyEntity1> MyEntityRepo1 { get; set; }
protected IRepository<MyEntity2> MyEntityRepo2 { get; set; }
protected IRepository<MyEntity3> MyEntityRepo3 { get; set; }
protected IRepository<MyEntity4> MyEntityRepo4 { get; set; }
protected IRepository<MyEntity5> MyEntityRepo5 { get; set; }
protected IRepository<MyEntity6> MyEntityRepo6 { get; set; }
public DefaultTemplateManager(IRepository<MyEntity1> MyEntityRepository1, IRepository<MyEntity2> MyEntityRepository2, IRepository<MyEntity3> MyEntityRepository3, IRepository<MyEntity4> MyEntityRepository4, IRepository<MyEntity5> MyEntityRepository5, IRepository<MyEntity6> MyEntityRepository6, ) {
this.MyEntityRepo1 = MyEntityRepository1;
this.MyEntityRepo2 = MyEntityRepository2;
this.MyEntityRepo3 = MyEntityRepository3;
this.MyEntityRepo4 = MyEntityRepository4;
this.MyEntityRepo5 = MyEntityRepository5;
this.MyEntityRepo6 = MyEntityRepository6;
}
public ProcessResponse Process(string UniqueKey) {
/* Do Work */
}
I'm creating a WPF MVVM application using Simple Injector as DI container. Now I'm having some issues when I'm trying to resolve a view from Simple Injector, because I'm in need of passing a parameter into my constructor at construction time (not when registering the view to the container, thus this is not applicable: Simple Injector pass values into constructor).
What I'm after is something like this:
var item = container.GetInstance<MyType>(myParameter);
I've read several places that this is not possible in Simple Injector because it should not be done (including here: https://simpleinjector.codeplex.com/discussions/397080).
Is this true, and if so, how could I do this instead?
Background information
I have a collection of multiple view models and models which are looked up by a specific key, and the parameter I want to pass into the view is the key for the view model to use. I've found this necessary because the view models and the models are used in multiple locations of the application, and need to stay in sync / be the same instances if they have the same key. I don't think I'm able to use lifetime scope to solve this, and there is no way I know the keys when I'm registering to the container. I've also understood that the ViewModelLocator approach might be the ServiceLocator (anti-?)pattern, however, currently it is the best I've got.
My constructor currently looks like this, and I want the IViewModelLocator to be resolved, while I pass in the key:
public FillPropertiesView(IViewModelLocator vml, object key)
{
// .. Removed code
// Assign the view model
var viewModel = vml.GetViewModel<FillPropertiesViewModel>(key);
DataContext = viewModel;
}
The IViewModelLocator looks like the following (and a similar interface exists for models).
public interface IViewModelLocator
{
// Gets the view model associated with a key, or a default
// view model if no key is supplied
T GetViewModel<T>(object key = null) where T : class, IViewModel;
}
Now I have the following questions:
What is the best way to be able to resolve the view with the view model key?
Do I have to do some refactoring to enable this?
Am I missing out on some of the power of the DI container since I have created my own dictionary based ViewModelLocator?
Extended information
I have shown the ViewModelLocator above, and the reason I'm using this is to keep blendability (basically it just provides me with design time data when opened in Blend). The runtime view model could have been the same for every instance of the view (not dependent on the key), if I did not have to have different windows opened at the same time (see next paragraph). The issue described above, however, is the same when the ViewModel is fetching a model, and the ModelLocator needs a key to fetch an existing model if it exists.
This is part of a VSTO application targeting PowerPoint (which affects some parts of the design). When an object on screen is selected, a task panel is opened (this is basically the FillPropertiesView explained above). The object that is selected has a key that is supplied to the view, in order for the view to extract the correct view model from the ViewModelLocator. The view model will then get a reference to a model by using a IModelLocator (similar to the IViewModelLocator) and the same key. At the same time, a controller will fetch the model from the ModelLocator by using the same key. The controller listens to change events from the model and updates the objects on screen. The same process is replicated whenever a new object is selected, and at the same time multiple windows could be open that interacts with the same or different objects simultaneously (that is, with multiple task panes all with unique view models).
Up until now I have resolved the view with a default, parameterless constructor, and then injected the view model with a method call afterwards:
// Sets the view model on a view
public void SetViewModel(IViewModelLocator vml, object key)
{
// Assign the view model
_viewModel = vml.GetViewModel<FillPropertiesViewModel>(key);
DataContext = _viewModel;
}
I never had to register the view with the container, but resolved the concrete type like this:
string key = "testkey" // read from the selected object
var view = container.GetInstance<FillPropertiesView>();
var vml = container.GetInstance<IViewModelLocator>();
view.SetViewModel(vml, key);
This issue surfaced when I tried to refactor this so that I did not have to call the SetViewModel() method every and manually resolve the view models etc. It got very messy when I also had to do this manual initiation within the view model to initiate the model in the same way.
ViewModelLocator
The ViewModelLocator is currently working as a wrapper around the DI container, i.e. the view models are registered in Simple Injector.
The registrations are like the following (in a class called CompositionHost):
container.RegisterSingle<IViewModelLocator, ViewModelLocator>();
container.RegisterSingle<IModelLocator, ModelLocator>();
The implementation looks like this:
// Base implementation used by ViewModelLocator and ModelLocator
public class ServiceLocator<TService> where TService : class
{
private readonly Dictionary<CombinedTypeKey, TService> _instances =
new Dictionary<CombinedTypeKey, TService>();
// Gets a service instance based on the type and a key.
// The key makes it possible to have multiple versions of the same service.
public T GetInstance<T>(object key = null) where T : class, TService
{
var combinedKey = new CombinedTypeKey(typeof(T), key);
// Check if we already have an instance
if (_instances.ContainsKey(combinedKey))
{
return _instances[combinedKey] as T;
}
// Create a new instance
// CompositionHost is a static reference to the DI container (and
// should perhaps be injected, however, that is not the main issue here)
var instance = CompositionHost.GetInstance<T>();
_instances.Add(combinedKey, instance);
return instance;
}
// A combined key to ease dictionary operations
private struct CombinedTypeKey
{
private readonly object _key;
private readonly Type _type;
public CombinedTypeKey(Type type, object key)
{
_type = type;
_key = key;
}
// Equals and GetHashCode() are overridden
}
}
public class ViewModelLocator : IViewModelLocator
{
private readonly ServiceLocator<IViewModel> _viewModelLocator;
public ViewModelLocator(ServiceLocator<IViewModel> locator)
{
_viewModelLocator = locator;
// Dummy code that registers design time data is removed
}
// IViewModel is just an empty interface implemented by the view models
public T GetViewModel<T>(object key = null) where T : class, IViewModel
{
return _viewModelLocator.GetInstance<T>(key);
}
}
Injecting a service locator into your classes is (almost) never the way to go, because this disallows compile time checking of dependencies and runtime dependency analysis. For that reason I can also advice to register ALL your root types (such as your views) since otherwise Simple Injector is left in the dark and is not able to advice you about any possible misconfigurations that you might have.
Since you have View + ViewModel pairs that are always cached together, but might depend on Model instance that are reused by multiple View + ViewModel pairs, I suggest the following design.
Define an abstraction for views and view models:
public interface IView<TModel>
{
IViewModel<TModel> ViewModel { get; }
}
public interface IViewModel<TModel>
{
TModel Model { get; set; }
}
Define an abstraction for retrieving/caching view by key.
public interface IViewProvider<TView, TModel> where TView : IView<TModel>
{
TView GetViewByKey(object key);
}
With these abstractions your view can look as follows:
public class FillPropertiesView : IView<FillPropertiesModel>
{
public FillPropertiesView(FillPropertiesViewModel viewModel)
{
this.ViewModel = viewModel;
}
public IViewModel<FillPropertiesModel> ViewModel { get; private set; }
}
And your controllers can depend upon the IViewProvider<TView, TModel> abstraction so they can reload the view when a new key is coming in:
public class FillPropertiesController : Controller
{
IViewProvider<FillPropertiesView, FillPropertiesModel> viewProvider;
FillPropertiesView view;
public FillPropertiesController(
IViewProvider<FillPropertiesView, FillPropertiesModel> provider) {
this.viewProvider = provider;
}
public void Reinitialize(object key) {
this.view = this.viewProvider.GetViewByKey(key);
}
}
The implementation for IViewProvider<TView, TModel> could look like this:
public class ViewProvider<TView, TModel> : IViewProvider<TView, TModel>
where TView : class, IView<TModel> {
Dictionary<object, TView> views = new Dictionary<object, TView>();
Container container;
IModelProvider<TModel> modelProvider;
public ViewProvider(Container container,
IModelProvider<TModel> modelProvider) {
this.container = container;
this.modelProvider = modelProvider;
}
public TView GetViewByKey(object key) {
TView view;
if (!this.views.TryGetValue(key, out view)) {
this.views[key] = view = this.CreateView(key);
}
return view;
}
private TView CreateView(object key) {
TView view = this.container.GetInstance<TView>();
view.ViewModel.Model = this.modelProvider.GetModelByKey(key);
return view;
}
}
This implementation depends on a (previously undefined) IModelProvider<TModel> abstraction. This is basically your old ModelLocator, but by using a generic type you can make the implementation much easier, because we can have one instance of this type per TModel (the same holds for ViewProvider), which saves you from having to do things with storing elements with the { Type + key } combination.
You can register this all as follows:
Assembly asm = Assembly.GetExecutingAssembly();
container.RegisterManyForOpenGeneric(typeof(IView<>), asm);
container.RegisterManyForOpenGeneric(typeof(IViewModel<>), asm);
container.RegisterOpenGeneric(typeof(IViewProvider<,>),
typeof(ViewProvider<,>), Lifestyle.Singleton);
container.RegisterOpenGeneric(typeof(IModelProvider<>),
typeof(ModelProvider<>), Lifestyle.Singleton);
var controllers =
from type in asm.GetTypes()
where type.IsSubClassOf(typeof(Controller))
where !type.IsAbstract
select type;
controllers.ToList().ForEach(t => container.Register(t));
container.Verify();
With RegisterManyForOpenGeneric you let Simple Injector search the supplied assemblies to look for implementations of the given open generic abstraction and Simple Injector will batch-register them for you. With RegisterOpenGeneric you specify an open-generic abstraction and tell Simple Injector which implementation to use when a close-generic version of that abstraction is requested. The last line searches through your application to look for all controller types and registers them in the system.
Does anyone have any example code for getting Umbraco MVC working with the Castle Windsor dependency injection framework? The problem I'm having is getting my surface controllers to use injectable parametised constructors. I know I'm doing something wrong but not sure what.
I have followed the (non-Umbraco) tutorial here - http://docs.castleproject.org/Windsor.Windsor-tutorial-part-four-putting-it-all-together.ashx - which basically means on App_Start I'm running this code:
var container = new WindsorContainer().Install(FromAssembly.This());
var controllerFactory = new MyCustomControllerFactory(container.Kernel);
ControllerBuilder.Current.SetControllerFactory(controllerFactory);
Code for MyCustomControllerFactory is below.
Also, my implementation of IWindsorInstaller contains the following:
container.Register(Classes.FromThisAssembly()
.BasedOn<SurfaceController>()
.LifestyleTransient());
The exception I'm getting is 'No component for supporting the service Umbraco.Web.Mvc.RenderMvcController was found', thrown by the GetControllerInstance method below when I call a surface controller with a parametised constructor:
public class TestSurfaceController : SurfaceController
{
public TestSurfaceController(INameService nameService)
{
....
}
}
If anyone has some example code which works I'd really appreciate it. I've wired up Ninject with Umbraco before with no trouble, but on this project I'm tied to Castle Windsor and getting nowhere fast! Thanks in advance.
MyCustomControllerFactory.cs:
public class MyCustomControllerFactory : DefaultControllerFactory
{
private readonly IKernel kernel;
public FastStartControllerFactory(IKernel kernel)
{
this.kernel = kernel;
}
public override void ReleaseController(IController controller)
{
kernel.ReleaseComponent(controller);
}
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
if (controllerType == null)
{
throw new HttpException(404, string.Format("The controller for path '{0}' could not be found.", requestContext.HttpContext.Request.Path));
}
return (IController)kernel.Resolve(controllerType);
}
}
I believe your problem is here:
ControllerBuilder.Current.SetControllerFactory(controllerFactory);
This is replacing the controller factory for ALL controllers, including the RenderMVCController, and Castle can't find a matching component for that type.
The trick is to use the FilteredControllerFactoryResolver, which lets Umbraco decide which controller to use based on some criteria that you provide (in this case, whether your container can resolve the controller type). Composition is not as clean as in a straight MVC app (IMHO), but it works.
Here's an (Umbraco 7.x) example of a filtered controller that implements the IFilteredControllerFactory interface:
public class FilteredControllerFactory : ControllerFactory, IFilteredControllerFactory
{
public bool CanHandle(RequestContext request)
{
Type controllerType = GetControllerType(request, request.RouteData.Values["controller"].ToString());
return ApplicationStartup.Container.Kernel.HasComponent(controllerType);
}
}
And the corresponding code to set up composition (using ApplicationEventHandler):
public class ApplicationStartup : ApplicationEventHandler
{
internal static IWindsorContainer Container;
protected override void ApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
base.ApplicationStarting(umbracoApplication, applicationContext);
Container = new WindsorContainer()
.Install(Configuration.FromAppConfig())
.Register(Classes.FromThisAssembly().BasedOn<IController>().LifestyleTransient());
FilteredControllerFactoriesResolver.Current.InsertType<FilteredControllerFactory>(0);
}
}
This approach should work both for route hijacking and for surface controllers.
Finally, note that if you also want to support injection into API controllers, you'll need to wire this up separately. For example:
GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerActivator), new CompositionRoot(Container.Kernel))
where CompositionRoot is your own Windsor composition root class.
The Gist here may also prove useful.
I've read Kristopher's answer and I've found it interesting, because I didn't know IFilteredControllerFactory and its use. Thanks for sharing.
Anyway, usually in my projects I have a lot of dll containing each its own controllers, so I prefer to register all the controllers in a more general way:
container.Register(
Classes
.FromAssemblyInDirectory(new AssemblyFilter(AssemblyDirectory))
.BasedOn<IController>()
.LifestyleTransient());
where
/// <summary>
/// Local Directory where are present all the assemblies
/// </summary>
static public string AssemblyDirectory
{
//Snippet code from: https://gist.github.com/iamkoch/2344638
get
{
var codeBase = Assembly.GetExecutingAssembly().CodeBase;
var uri = new UriBuilder(codeBase);
var path = Uri.UnescapeDataString(uri.Path);
return Path.GetDirectoryName(path);
}
}
In this way also the Umbraco's RenderMVCController will be mapped and correctly resolved.
Recently I wrote a couple of articles about DI in a Umbraco app:
MVC Controller Factory
Properties Injection in MVC Filters
Hope it can help
I have the following classes / interfaces:
public interface IProjectRepository
{
IQueryably<Project> GetProjects();
}
// Depends on my EF Context
public ProjectRepository : IProjectRepository
{
private MyDbEntities context;
public ProjectRepository(MyDbEntities context)
{
this.context = context;
}
public IQueryable<Project> GetProjects()
{
return context.Projects;
}
}
My controller:
// Depends on IProjectRepository
public class ProjectsController : Controller
{
private IProjectRepository projectRepository;
public ProjectsController(IProjectRepository projectRepository)
{
this.projectRepository = projectRepository;
}
public ActionResult Index()
{
return View(projectRepository.GetProjects());
}
}
I need to set up my dependency injection so that it passes in ProjectRepository into my Controller AND it needs to pass in my Entity Framework context into the Project Repository. I need to Entity Context to be HTTP Request scoped.
I'm not sure where I am supposed to put all the mapping code to make the dependency injection work. I also don't understand how MVC will work without the default constructor.
Can someone help me put all the pieces together? I am using StructureMap but I could easily switch to something else because I have no idea what I'm doing.
If you are using MVC 3, to do things properly, you should make use of the built in dependency resolution bits. I would highly recommend you read through the series of blog posts from Brad Wilson (member of the ASP.NET MVC team).
As far as a StructureMap specific implementation, I found the following blog posts helpful.
StructureMap and ASP.NET MVC 3 – Getting Started
StructureMap, Model Binders and Dependency Injection in ASP.NET MVC 3
StructureMap, Action Filters and Dependency Injection in ASP.NET MVC 3
StructureMap, Global Action Filters and Dependency Injection in ASP.NET MVC 3
Anyway, here's some code. To start with, I would suggest that you install the StructureMap-MVC3 NuGet package.
I can't remember what exactly it creates in the way of files, but here's what's basically involved.
/App_Start/StructuremapMvc.cs - This hooks into the Application_Start and sets up your container (SmIoC.Initialize()) and then sets the MVC 3 DependencyResolver to a your SmDependencyResolver
using System.Web.Mvc;
using YourAppNamespace.Website.IoC;
using StructureMap;
[assembly: WebActivator.PreApplicationStartMethod(typeof(YourAppNamespace.App_Start.StructuremapMvc), "Start")]
namespace YourAppNamespace.Website.App_Start {
public static class StructuremapMvc {
public static void Start() {
var container = SmIoC.Initialize();
DependencyResolver.SetResolver(new SmDependencyResolver(container));
}
}
}
/IoC/SmDependencyResolver.cs - this is your MVC 3 IDependencyResolver implementation. It's used in the App_Start code above.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using StructureMap;
namespace YourAppNamespace.Website.IoC
{
public class SmDependencyResolver : IDependencyResolver
{
private readonly IContainer _container;
public SmDependencyResolver(IContainer container)
{
_container = container;
}
public object GetService(Type serviceType)
{
if (serviceType == null)
{
return null;
}
try
{
return _container.GetInstance(serviceType);
}
catch
{
return null;
}
}
public IEnumerable<object> GetServices(Type serviceType)
{
return _container.GetAllInstances(serviceType).Cast<object>(); ;
}
}
}
/IoC/SmIoC.cs - this is where you setup your container... also used in the App_Start code.
namespace YourAppNamespace.Website.IoC
{
public static class SmIoC
{
public static IContainer Initialize()
{
ObjectFactory.Initialize(x =>
{
x.For<IProjectRepository>().Use<ProjectRepository>();
//etc...
});
return ObjectFactory.Container;
}
}
}
Now everything is hooked up... (I think ;-) but you still have one last thing to do. Inside your Global.asax, we need to make sure you dispose of everything that is HttpContext scoped.
protected void Application_EndRequest()
{
ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects();
}
So you should be able to achieve dependency injection through constructor injection, which is the correct way to go about doing things.
If you are set on using StructureMap, here is a tutorial on the setup that you will probably need.
Some other dependency injection frameworks come with custom controller factories which will do that for you. Ninject (open source dependency injection), for example has an extension that you can use that contains this behaviour. See here for example. And here to the extension.
You can use also Unity IOC which is another popular dependency injection framework with which, to my knowledge, you will have to create a custom controller factory (like with structuremap) to achieve this behaviour. See here for an example.
You can also research all other dependency injection frameworks to see what support you can get with each.
EDIT:
I hope I am explaining this correctly but here is some background info.
MVC uses a controller factory that has the responsibilities of instantiating the respective controllers needed when a request is made. By default, it will initialize a controller by calling its parameterless constructor.
To create the infrastructure for the constructor parameter injection you need to create a custom factory that can resolve constructor parameters. That is where the dependency injection containers come in: essentially the DI container (if configured properly) knows how to resolve those dependency and your custom factory will leverage it to request the registered dependencies and pass the to the controller constructor.
All work pretty much the same. Historically, all have had setter injectors (set up a property that is then filled), but most have constructor injection now. In structure map, the easiest way to accomplish this is use the attribute: [StructureMap.DefaultConstructor].
Once you add the attribute, the objects you have placed in your "map" should inject without any extra work. If you can't use attributes, consider using the setter.
There is a file on the structure map site:
http://structuremap.net/structuremap/ConstructorAndSetterInjection.htm
When using StructureMap I would generally have something like this in my controller:
private static IProjectRepository GetProjectRepository()
{
var retVal = ObjectFactory.TryGetInstance<IProjectRepository>()
?? new ProjectRepository();
return retVal;
}
If the TryGetInstance returns null (because nothing was set for that type) it will default to the concrete type you specify.
Now you have a bootstrapper somewhere like this:
public static class StructureMapBootStrapper
{
public static void InitializeStructureMap()
{
ObjectFactory.Initialize(x =>
{
x.For<IProjectRepository>().Use<ProjectRepository>();
}
}
}
Now you call this bootstrapper in your Global.asax Application_Start event:
protected void Application_Start()
{
StructureMapBootStrapper.InitializeStructureMap();
}
Now in a test project, when you want to inject a mock repository you can just do this:
[TestMethod]
public void SomeControllerTest()
{
StructureMap.ObjectFactory.Inject(
typeof(IProjectRepository),
new MockProjectRepository());
// ... do some test of your controller with the mock
}
I am looking at depency injection, I can see the benefits but I am having problems with the syntax it creates. I have this example
public class BusinessProducts
{
IDataContext _dx;
BusinessProducts(IDataContext dx)
{
_dx = dx;
}
public List<Product> GetProducts()
{
return dx.GetProducts();
}
}
The problem is that I don't want to write
BusinessProducts bp = new BusinessProducts(dataContextImplementation);
I would continue to write
BusinessProducts bp = new BusinessProducts();
because I feel the first alternative just feels unatural. I dont want to know what the BusinessProduct "depends" on to get the products, also I feel it makes my code more unreadable.
Is there any alternatives to this approach as I would like to keep my original syntax for creating objects but I would like to still be able to fake the dependencies when unit testing or is it this dependecy injection frameworks can do for me?
I am coding in c# but alternatives from other languages is welcome
I use a factory for my context and inject it, providing a suitable default if the provided factory is null. I do this for two reasons. First, I use the data context as a unit of work scoped object so I need to be able to create them when needed, not keep one around. Second, I'm primarily using DI to increase testability, with decoupling only a secondary consideration.
So my business products class would look like:
public class BusinessProducts
{
private IDataContextFactory DataContextFactory { get; set; } // my interface
public BusinessProducts() : this(null) {}
public BusinessProducts( IDataContextFactory factory )
{
this.DataContext = factory ?? new BusinessProductsDataContextFactory();
}
public void DoSomething()
{
using (DataContext dc = this.DataContextFactory().CreateDataContext())
{
...
}
}
An alternative to this would be to make the factory property publicly settable and inject an alternate factory by setting the property. Either way if you want to keep the null constructor, you'll need to provide a default.
You can create a factory. DI containers are best for wirings that happen at setup-time - not at runtime (As this looks to be a case of). Factories can be implemented in different ways, depending on how pluggable it needs to be, and how many places you need to use it.
I would usually have an empty constructor which uses a solid instance( or an instances created by IoC), amd one with DI. i.e.
public class BusinessProducts
{
IDataContext _dx;
BusinessProducts()
{
_dx = new SolidDataContext();
}
BusinessProducts(IDataContext dx)
{
_dx = dx;
}
}
This way you can use DI for overriding the default instance in unit testing testing.
Your feelings, while valid, are misplaced.
The Dependency Injection pattern is a direct application of the Inversion of Control principle.
This means that, instead of your class controlling the instances of other classes it consumes, that relationship is inverted and the dependencies are provided to it.
As such, your classes naturally expose their dependencies via constructor arguments or properties. Showing disdain for this structure says you haven't truly grokked the pattern.
There are two distinct cases here:
In production code you will never write
new BusinessProducts(dataContextImplementation)
because dependency injection will normally be creating the full object hierarchy for you. This is the "viral" nature of dependency injection patterns, they tend to take over full control of your service creation.
In unit test code you will normally be creating this yourself, but quite often you will be supplying a mock object or a stub implementation of dataContextImplementation. So normally you will be injecting an object that does not have a large number of subsequent dependencies.
http://springframework.net/ and http://structuremap.sourceforge.net/Default.htm are probably the mostly used DI frameworks for .NET based languages and will both do what you need.
Generally the framework itself will have the logic to build up the entire object tree. For example, instead of
new SomeObjectO(diContext)
you would call the framework like this:
DIFramework.GetNew<SomeObjectO>();
or
DIFramework.Get<SomeObject>();
Another interesting framework to take a look at if you would like to learn about DI and the process is Microsoft's Unity and Object Builder projects.
If you really do not like injecting this instance in the constructor, you might try to use the CommonServiceLocator with your favourite compatible .NET depedency injection framework. This would allow you to write code like this:
public class BusinessProducts
{
IDataContext _dx;
BusinessProducts()
{
_dx = Microsoft.Practices.ServiceLocation.ServiceLocator.Current.GetInstance<IDataContext>();
}
public List<Product> GetProducts()
{
return dx.GetProducts();
}
}
However, please beware that this is not what most people would expect when they know that you use a dependency injection framework. I think that it is much more common to use a dependency injection framework and letting it create all objects for you.
BusinessProducts bp = Microsoft.Practices.ServiceLocation.ServiceLocator.Current.GetInstance<BusinessProducts>();
If you would like to avoid the dependeny injection framework path, using a factory is probably the best way to go.
There's a technique called poor man's DI that looks like this
public class BusinessProducts
{
IDataContext _dx;
BusinessProducts() : this(new DataContext()) {}
BusinessProducts(IDataContext dx)
{
_dx = dx;
}
public List<Product> GetProducts()
{
return dx.GetProducts();
}
}
This is not ideal since it ties you to the implementation but its a good stepping stone towards decoupled code. this is similar to #tvanfosson but a lot simplier.
I second the recommendation for Windsor
My code will reference Microsoft Unity but I am sure it is pretty applicable to all DI frameworks. If you're using DI correctly you never need to call new BusinessObject(new dataContext) the DI association will handle it all for you.
My example will be a little bit long since I will paste in some code I use for running a Model View Presenter website fully DI loaded by Unity. (If you want the full source check out my blog and download it from my Assembla SVN server)
Load the container (can be in code like I prefer or using configuration)
protected void Application_Start(object sender, EventArgs e)
{
Application.GetContainer()
// presenters / controllers are per request
.RegisterType<IEmployeeController, EmployeeController>(new ContextLifetimeManager<IEmployeeController>())
//Data Providers are Per session
.RegisterType<IEmployeeDataProvider, EmployeeDataProvider>(new SessionLifetimeManager<IEmployeeDataProvider>())
//Session Factory is life time
.RegisterType<INHibernateSessionManager, NHibernateSessionManager>(new ContainerControlledLifetimeManager());
}
Custom HTTP module calls Unity BuildUp Method for each page during the OnPreRequest invocation.
private static void OnPreRequestHandlerExecute(object sender, EventArgs e)
{
var handler = HttpContext.Current.Handler;
HttpContext.Current.Application.GetContainer().BuildUp(handler.GetType(), handler);
// User Controls are ready to be built up after the page initialization is complete
var page = HttpContext.Current.Handler as Page;
if (page != null)
{
page.InitComplete += OnPageInitComplete;
}
}
Page container presenter decorated with [Dependency] attribute
public partial class Employees : Page, IEmployeeView
{
private EmployeePresenter _presenter;
[Dependency]
public EmployeePresenter Presenter
{
set
{
_presenter = value;
_presenter.View = this;
}
}
}
Presenter with InjectionConstructor method
public class EmployeePresenter : Presenter<IEmployeeView>
{
private readonly IEmployeeController _controller;
[InjectionConstructor]
}
public EmployeePresenter(IEmployeeController controller)
{
_controller = controller;
}
Controller follows suit
public class EmployeeController : IEmployeeController
{
private readonly IEmployeeDataProvider _provider;
[InjectionConstructor]
public EmployeeController(IEmployeeDataProvider DataProvider)
{
_provider = DataProvider;
}
}
Same with provider
public class EmployeeController : IEmployeeController
{
private readonly IEmployeeDataProvider _provider;
[InjectionConstructor]
public EmployeeController(IEmployeeDataProvider DataProvider)
{
_provider = DataProvider;
}
}
Lastly the session manager, which contains only a regular constructor.
public class NHibernateSessionManager : INHibernateSessionManager
{
private readonly ISessionFactory _sessionFactory;
public NHibernateSessionManager()
{
_sessionFactory = GetSessionFactory();
}
}
So what happens when a page request is started the BuildUp() method is called on the page by the HttpModule. Unity then sees the Property marked with the Dependency attribute and will check it's container to see if inside it exists an EmployeePresenter object.
Since there is no such object in the container it will then try to create an EmployeePresenter. Upon inspection to create the class it sees inside the Presenter it requires a constructor that needs a IEmployeeController injected into it. Since the container actually has a manager for the controller it will see if an instance of it exists in the container which on the beginning of the page request doesn't exist, so it will go to instantiate the controller.
Unity will then see the controller requires a IEmployeeDataProvider injected into it, and it will continue on this process until it finally gets to the point where the Provider needs the session manager injected. Since the session manager has no more need for injection Unity will then create an instance of the session manager store it in the container for it's given ContainerLifeTimeManager, inject it into the Provider and store that instance, and so on down to where it finished creating a EmployeePresenter dependency for the page.
you can also look at windsor for IoC .