Web Api Start up Exceptions with IDependencyResolver implementation - dependency-injection

I am developing a Web Api and I decided to use custom DependencyResolver. I refer this [Dependency Injection for Web API Controllers] article. Everything is working well so far in the terms of dependency injection into controllers. Code snippet of my configuration from my Owin startup class
private void RegisterIoC(HttpConfiguration config)
{
_unityContainer = new UnityContainer();
_unityContainer.RegisterType<IAccountService, AccountService>();
.........
.........
config.DependencyResolver = new UnityResolver(_unityContainer);
}
But at the time when Api starts for the very first time some ResolutionFailedException thrown (but catched) inside the UnityResolver's GetService method. Here is the exception message
"Exception occurred while: while resolving.
Exception is: InvalidOperationException -
The current type, System.Web.Http.Hosting.IHostBufferPolicySelector,
**is an interface and cannot be constructed. Are you missing a type mapping?**"
Above same exception thrown following types
System.Web.Http.Hosting.IHostBufferPolicySelector
System.Web.Http.Tracing.ITraceWriter
System.Web.Http.Metadata.ModelMetadataProvider
System.Web.Http.Tracing.ITraceManager
System.Web.Http.Dispatcher.IHttpControllerSelector
System.Web.Http.Dispatcher.IAssembliesResolver
System.Web.Http.Dispatcher.IHttpControllerTypeResolver
System.Web.Http.Controllers.IHttpActionSelector
System.Web.Http.Controllers.IActionValueBinder
System.Web.Http.Validation.IBodyModelValidator
System.Net.Http.Formatting.IContentNegotiator
I know that these ResolutionFailedException are thrown because I did not provide mappings in my unity configuration for above types.
Now here is my question :-, If I implement custom unity DependencyResolver I need to define mappings of above types and if need to define what will be their corresponding default implementation types OR is there some alternative way to implement DependencyResolver. I am really concerned even though application is running fine now, failing to resolve above type can cause serious issue later. Please help.
One final Addition:-
For following types, same ResolutionFailedException thrown when I make request for any action into the my web api
System.Web.Http.Dispatcher.IHttpControllerActivator
System.Web.Http.Validation.IModelValidatorCache
System.Web.Http.Controllers.IHttpActionInvoker

I was running in to the same issue using Unity with WebApi and OWIN/Katana.
The solution for me was to use the UnityDependencyResolver defined in the Unity.WebApi Nuget package instead of my own custom implementation (like #Omar Alani above)
Install-Package Unity.WebAPI
Note that the package will try and add a file named UnityConfig.cs in App_Start (the filename I used myself).
In that UnityConfig.cs file the package will add code to register the container against the GlobalConfiguration.Configuration.DependencyResolver which is not what we want with OWIN.
So instead of using:
GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
Change to use:
config.DependencyResolver = new UnityDependencyResolver(container);
For completeness:
My UnityConfig.cs
public static class UnityConfig
{
public static void Register(HttpConfiguration config)
{
var container = new UnityContainer();
// Your mappings here
config.DependencyResolver = new UnityDependencyResolver(container);
}
}
My Startup.cs
[assembly: OwinStartup(typeof(UnityTest.BusinessLayer.Api.ApiStartup))]
namespace UnityTest.BusinessLayer.Api
{
public partial class ApiStartup
{
public void Configuration(IAppBuilder app)
{
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
HttpConfiguration httpConfig = new HttpConfiguration();
UnityConfig.Register(httpConfig);
ConfigureAuth(app); //In App_Start ->Startup.Auth
WebApiConfig.Register(httpConfig);
app.UseWebApi(httpConfig);
}
}
}

In case any of the above solutions still don't work for people, here's how I solved it.
After spending a day chasing down this error, it turned out to be some sort of VS caching issue. Out of desperation, I deleted all .suo files and force-get-latest, which seems to have resolved the issue.

This has been asked a long time ago, but I encountered a solution that wasn't mentioned here so maybe someone is still interested.
In my case, these exceptions were already caught internally by Unity (or whatever), but my Exception Settings in Visual Studio made them still show up. I just had to uncheck the "Break when this exception type is shown" check box and the application went on functioning normally.

The implementation of Unity.WebAPI is not very different from the one mentioned in the question. I liked the version referred to by the OP as it ignores only ResultionFailedException and lets the rest propagate up the stack. Unity.WebAPI suppresses all exceptions. What I'd do is ignore errors that we know are safe to do so and log (or rethrow) others.
public object GetService(Type serviceType)
{
try
{
return container.Resolve(serviceType);
}
catch(ResolutionFailedException ex)
{
if (!(typeof(System.Web.Http.Tracing.ITraceWriter).IsAssignableFrom(serviceType))
|| typeof(System.Web.Http.Metadata.ModelMetadataProvider).IsAssignableFrom(serviceType)
//...
))
{
// log error
}
}
return null;
}

Normally, you don't need to with Unity.
I use this implementation for IDependencyResolver with unity, and I don't have to register or map other than my interfaces/services.
public class UnityDependencyInjectionResolver : Disposable, IDependencyResolver
{
protected IUnityContainer Container;
public UnityDependencyInjectionResolver(IUnityContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
Container = container;
}
public object GetService(Type serviceType)
{
try
{
return Container.Resolve(serviceType);
}
catch (ResolutionFailedException)
{
return null;
}
}
public T GetService<T>()
{
try
{
var serviceType = typeof(T);
return (T)Container.Resolve(serviceType);
}
catch (ResolutionFailedException)
{
return default(T);
}
}
public T GetService<T>(string name)
{
try
{
var serviceType = typeof (T);
return (T) Container.Resolve(serviceType, name);
}
catch (ResolutionFailedException)
{
return default(T);
}
}
public IEnumerable<object> GetServices(Type serviceType)
{
try
{
return Container.ResolveAll(serviceType);
}
catch (ResolutionFailedException)
{
return new List<object>();
}
}
public IDependencyScope BeginScope()
{
var child = Container.CreateChildContainer();
return new UnityDependencyInjectionResolver(child);
}
protected override void DisposeManagedResources()
{
if (Container == null)
{
return;
}
Container.Dispose();
Container = null;
}
}
where Disposable is just a base class implements IDispoable.
Hope that helps.

As this seems to still get disputed, here's my version of the code...
/// <summary>
/// Specifies the Unity configuration for the main container.
/// </summary>
public class UnityConfig
{
private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() =>
{
var container = new UnityContainer();
RegisterTypes(container);
return container;
});
/// <summary>
/// Gets the configured Unity container.
/// </summary>
public static IUnityContainer GetConfiguredContainer()
{
return container.Value;
}
public static void RegisterTypes(IUnityContainer container)
{
// Keeping this separate allows easier unit testing
// Your type mappings here
}
}
and
[assembly: OwinStartup(typeof(UnityTest.BusinessLayer.Api.ApiStartup))]
namespace UnityTest.BusinessLayer.Api
{
public static HttpConfiguration Config { get; private set; }
public partial class ApiStartup
{
public void Configuration(IAppBuilder app)
{
// IoC
var container = UnityConfig.GetConfiguredContainer();
var resolver = new UnityHierarchicalDependencyResolver(container); // Gets us scoped resolution
app.UseDependencyResolverScope(resolver); // And for the OWIN
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
// NB Must be before WebApiConfig.Register
ConfigureAuth(app); //In App_Start ->Startup.Auth
// See http://stackoverflow.com/questions/33402654/web-api-with-owin-throws-objectdisposedexception-for-httpmessageinvoker
// and http://aspnetwebstack.codeplex.com/workitem/2091
#if SELFHOST
// WebAPI configuration
Config = new HttpConfiguration
{
DependencyResolver = resolver
};
WebApiConfig.Register(Config);
app.UseWebApi(Config);
#else
GlobalConfiguration.Configuration.DependencyResolver = resolver;
// http://stackoverflow.com/questions/19907226/asp-net-webapi-2-attribute-routing-not-working
// Needs to be before RouteConfig.RegisterRoutes(RouteTable.Routes);
GlobalConfiguration.Configure(WebApiConfig.Register);
Config = GlobalConfiguration.Configuration;
#endif
// Now do MVC configuration if appropriate
}
}
}
Finally bits are the extensions to use the scoped container in the Owin middleware as well as straight WebAPI
public static class AppBuilderExtensions
{
public static IAppBuilder UseDependencyResolverScope(this IAppBuilder app, IDependencyResolver resolver)
{
return app.Use<DependencyResolverScopeMiddleware>(resolver);
}
}
/// <summary>
/// Wraps middleware in a <see cref="IDependencyResolver"/> scope.
/// </summary>
public class DependencyResolverScopeMiddleware : OwinMiddleware
{
private readonly IDependencyResolver resolver;
public DependencyResolverScopeMiddleware(OwinMiddleware next, IDependencyResolver resolver) : base(next)
{
this.resolver = resolver;
}
public override async Task Invoke(IOwinContext context)
{
using (var scope = resolver.BeginScope())
{
context.SetDependencyScope(scope);
await Next.Invoke(context);
}
}
}
The rationale for this is the original MVC Work Item where we see
kichalla wrote Oct 27, 2014 at 4:34 PM
Yes...right...UseWebApi extension should be used only with
self-hosting scenarios...since we are all on the same page, I am
closing this issue as by-design...please let us know if you have any
more questions...
Thanks, Kiran
and
kichalla wrote Oct 29, 2014 at 5:28 PM
#thebothead: Thanks for finding this out!...right, this sample
shouldn't have been using Microsoft.AspNet.WebApi.Owin in IIS as it
was never intended to be used in that host...we will investigate the
issue further to see why this exception happens...but meanwhile you
could follow the approach mentioned in the sample that I provided
earlier...
Thanks, Kiran
From my own experience if you don't use this form of the code, it will work in debug etc but will not scale and start behaving strangely.

I has deleted dependencyResolver and this problem was solved
public static class UnityConfig
{
public static void Register(HttpConfiguration config)
{
var container = new UnityContainer();
// Your mappings here
config.DependencyResolver = null;
}
}

Related

Dependency Injection in ApplicationEventHandler. Bug?

Umbraco v7.5.8
I have bunch of problems with DI setup (shown below).
1) Neither OnApplicationInitialized, nor OnApplicationStarted (and other) events firing if constructor takes parameter(s).
2) Backoffice is broken. It's not possible to access a content node. Exception message is:
An error occurred when trying to create a controller of type 'ContentController'. Make sure that the controller has a parameterless public constructor.
// Application handlers
public class UmbracoApplicationEventHandler : IApplicationEventHandler
{
private IMenuManager _menuManager;
public UmbracoApplicationEventHandler(IMenuManager menuManager)
{
_menuManager = menuManager;
}
public void OnApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
ContentService.Saving += UpdateMenu;
}
private void UpdateMenu(IContentService sender, SaveEventArgs<IContent> saveEventArgs)
{
_menuManager.UpdateMenu();
}
}
// Unity config:
public static class UnityConfig
{
public static void RegisterComponents()
{
var container = new UnityContainer();
container.RegisterType<IMenuManager, MenuManager>();
GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
}
}
// Owin Startup:
public class UmbracoStandardOwinStartup : UmbracoDefaultOwinStartup
{
public override void Configuration(IAppBuilder app)
{
//ensure the default options are configured
base.Configuration(app);
UnityConfig.RegisterComponents();
}
}
Please read: https://our.umbraco.org/documentation/reference/using-ioc.
You need to register and build your container on OnApplicationStarted event, not earlier if you want to make it work with Umbraco.

Using Unity IoC to register and resolve SignalR hubs

I think I'm missing something very simple and maybe just need a new set of eyes. I have an ASP.NET MVC application. In that app, I am using Unity for my IoC to handle dependency injection. Each of my repositories need to have a database factory injected into it and each database factory needs to have a principal injected into it. So far, I've been utilizing the PerRequestLifetimeManager to register these.
//Repositories
container.RegisterType<ChatMessageRepository>(new PerRequestLifetimeManager());
container.RegisterType<SignalRConnectionRepository>(new PerRequestLifetimeManager());
//Context
container.RegisterType<IPrincipal, Principal>(new PerRequestLifetimeManager());
container.RegisterType<IDatabaseFactory, DatabaseFactory>(new PerRequestLifetimeManager());
container.RegisterType<UnitOfWork>(new PerRequestLifetimeManager());
Logically, I've tried to register my Hub in the same fashion.
container.RegisterType<ChatHub>(new PerRequestLifetimeManager());
However, whenever I run my app and navigate away from my chat page, I get a "Resolution of the dependency failed" exception and the InnerException tells me "Operation is not valid due to the current state of the object." I've also tried using the default (Transient), PerResolve, and ContainerControlled lifetime Unity managers when registering these guys and cannot seem to get resolve my issue.
Could someone just provide me some demo code with how you used Unity in an ASP.NET MVC application to handle dependency injection into your signalr hubs?
Here's where Unity will inject parameters into my SignalR Hub
public class ChatHub : Hub
{
private readonly ChatMessageRepository _chatMessageRepository;
private readonly SignalRConnectionRepository _signalRConnectionRepository;
private readonly UnitOfWork _unitOfWork;
public ChatHub(ChatMessageRepository chatMessageRepository,
SignalRConnectionRepository signalRConnectionRepository,
UnitOfWork unitOfWork)
{
_chatMessageRepository = chatMessageRepository;
_signalRConnectionRepository = signalRConnectionRepository;
_unitOfWork = unitOfWork;
} ... }
Thanks!
Do it in 3 steps
First. Create UnityHubActivator class
public class UnityHubActivator : IHubActivator
{
private readonly IUnityContainer _container;
public UnityHubActivator(IUnityContainer container)
{
_container = container;
}
public IHub Create(HubDescriptor descriptor)
{
return (IHub)_container.Resolve(descriptor.HubType);
}
}
Second. Create Unity container and register your dependency resolver before run Startup class
unityContainer = new UnityContainer();
var unityHubActivator = new UnityHubActivator(_unityContainer);
GlobalHost.DependencyResolver.Register(typeof(IHubActivator), () => unityHubActivator);
//register some types in container
WebApp.Start<Startup>(startOptions);
Third. Use it in your Hub
public class MyHub : Hub
{
public MyHub(Logger logger)
{
logger.Info("hub constructor");
}
}
Note. I do not change anything in my Startup class
There's a trick to do that. You will need to do something like this:
container.RegisterType< ChatHub >(new InjectionFactory(CreateChatHub));
......
and then create a private method CreateChatHub
private static object CreateChatHub(IUnityContainer container)
{
return new ChatHub();
}
1 Create "UnitySignalRDependencyResolver.cs"
public class UnitySignalRDependencyResolver : DefaultDependencyResolver
{
protected IUnityContainer Container;
private bool IsDisposed = false;
public UnitySignalRDependencyResolver(IUnityContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
Container = container.CreateChildContainer();
}
/// <summary>
/// Gets the Autofac implementation of the dependency resolver.
/// </summary>
public static UnitySignalRDependencyResolver Current
{
get { return GlobalHost.DependencyResolver as UnitySignalRDependencyResolver; }
}
public override object GetService(Type serviceType)
{
if (Container.IsRegistered(serviceType))
{
return Container.Resolve(serviceType);
}
return base.GetService(serviceType);
}
public override IEnumerable<object> GetServices(Type serviceType)
{
if (Container.IsRegistered(serviceType))
{
return Container.ResolveAll(serviceType);
}
return base.GetServices(serviceType);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (IsDisposed)
{
return;
}
if (disposing)
{
Container.Dispose();
}
IsDisposed = true;
}
}
2.Add your resolver to Owin pipeline
public class Startup
{
public void Configuration(IAppBuilder app)
{
// Get container
IUnityContainer container = UnityConfig.Container;
// Create resolver
var resolver = new UnitySignalRDependencyResolver(container);
// Create SignalR Configuration
var config = new HubConfiguration
{
Resolver = resolver
};
// Start SignalR
app.Map("/signalr", map =>
{
map.RunSignalR(config);
});
}
}
3.Inject your dependency in your controller's constructor
public class ValuesController : ApiController
{
private readonly IMyDependency _myDependency;
public ValuesController(IMyDependency myDependency)
{
_myDependency= myDependency;
}
}

How to use session values with Unity and DependencyResolver

I'm using MVC4 and Unity 2.1. My services require a service key based on credentials retrieved from session state.
I register my service(s) like so:
container.RegisterType<IInventoryService, InventoryService>();
The constructor for InventoryService is equally simple:
public InventoryService(ServiceKey serviceKey) { ... }
In my website when I've needed a service I use a service locator that automatically composes the service key using credentials from session.
public static T Resolve<T>(ServiceKey serviceKey = null)
{
if (serviceKey == null)
{
serviceKey = SessionManager.ServiceKey;
}
var parameterOverride = new ParameterOverride(SERVICEKEY_PARAMETERNAME, serviceKey);
return Resolve<T>(null, parameterOverride);
}
This has worked well. The problem is that I'm now converting my site to MVC and attempting to inject services into controllers using a simple dependency resolver that uses my exiting service locator (dependency factory):
public class CustomDependencyResolver : IDependencyResolver
{
public object GetService(Type serviceType)
{
return MvcDependencyFactory.Resolve(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return MvcDependencyFactory.ResolveAll(serviceType);
}
}
My controller looks like:
public InventoryController(IInventoryService inventoryService) { ... }
The problem is that MVC still complains about not finding a parameterless constructor when trying to instantiate the inventory controller. I think this is because I haven't registered a service key in Unity. But if I try doing so, I find that MVC is trying to resolve the controllers, and subsequently the services, before session has even been constructed.
Am I not thinking about this correctly? Each step feels pretty reasonable -- using session credentials in a service, using a service in a controller, using a resolver to help build the controller -- but I've been beating my head against the wall getting this to work.
You can use the InjectionFactory in Unity (Microsoft.Practices.Unity.InjectionFactory) to specify a function to handle the resolution of your dependency. This function will only be executed when the dependency is resolved. In the below example, "c" is your Unity container passed as a argument so that you can do additional resolves within your function.
replace:
container.RegisterType<IInventoryService, InventoryService>();
with:
container.RegisterType<IInventoryService>(new InjectionFactory(c =>
new InventoryService(SessionManager.ServiceKey)));
Using the Unity.Mvc4 package seemed to fix the problem, though it's not clear to me why. But rather than use yet another package and hide away my questions, I decided to add a parameterless constructor that manually resolves itself as necessary:
public InventoryController() : this (MvcDependencyFactory.Resolve<IInventoryService>(SessionManger.ServiceKey) { }
It still allows for unit testing of the controllers (via injection) while being transparent about where the resolution is happening when the parameterless constructor is called.
Below is a custom IDependencyResolver, which was fairly straight forward once I started to dig into how it worked and differed from IoC container resolution. You need the try/catches to capture MVC's attempted resolution of IControllerActivator (source: http://www.devtrends.co.uk/blog/do-not-implement-icontrolleractivator-in-asp.net-mvc-3). If IControllerActivator cannot be resolved, your custom IDependencyResolver will be queried for your controller instead (which will use your IoC container of choice).
I added the below class to my basic MVC4's App_Start folder:
using System;
using System.Collections.Generic;
using System.Web.Mvc;
using Microsoft.Practices.Unity;
using Sample.Web.Controllers;
namespace Sample.Web.App_Start
{
public static class UnityConfig
{
public static void ConfigureContainer()
{
IUnityContainer container = BuildUnityContainer();
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
}
private static IUnityContainer BuildUnityContainer()
{
var container = new UnityContainer();
container.RegisterType<IHomeService>(new InjectionFactory( c =>
new HomeService("this string is a dependency.")));
container.RegisterType<IController, HomeController>("Home");
return container;
}
}
public class UnityDependencyResolver : IDependencyResolver
{
private readonly IUnityContainer _container;
public UnityDependencyResolver(IUnityContainer container)
{
_container = container;
}
public object GetService(Type serviceType)
{
try
{
return _container.Resolve(serviceType);
}
catch (ResolutionFailedException)
{
return null;
}
}
public IEnumerable<object> GetServices(Type serviceType)
{
try
{
return _container.ResolveAll(serviceType);
}
catch (ResolutionFailedException)
{
return new List<object>();
}
}
}
}
Here is my simple controller:
using System.Web.Mvc;
namespace Sample.Web.Controllers
{
public class HomeController : Controller
{
private readonly IHomeService _service;
public HomeController(IHomeService service)
{
_service = service;
}
public ActionResult Index()
{
ViewBag.SomeData = _service.GetSomeData();
return View();
}
}
public interface IHomeService
{
string GetSomeData();
}
public class HomeService : IHomeService
{
private readonly string _data;
public HomeService(string data)
{
_data = data;
}
public string GetSomeData()
{
return _data;
}
}
}
Here is my epically huge view:
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>#ViewBag.SomeData</p>

Integrating Castle Windsor with SignalR - how should I approach this?

I am getting started with SignalR, and it works great once everything is configured. However, almost all the applications that I work on use Castle Windsor, so it would be great to be able to use them together. The reason that I want to do this is so that I can use Castle dependencies/services inside of a persistent connection.
I dug around in the source code, and it looks like I could either replace DependencyResolver with a Castle based one (i.e., Castle implementing IDependencyResolver), or I could change the usage of DependencyResolver to Castle.
Which one of these is a better idea? Is there another approach that I could use to combine Castle and SignalR?
Thanks,
Erick
August 2016 update
Following from a comment I no longer use the approach below but now use the GlobalHost.DependencyResolver
So in Global.asax.cs I initialise things
public static void Init(IWindsorContainer container)
{
var conn = configurationManager.ConnectionStrings["SRSQL"].ConnectionString;
GlobalHost.DependencyResolver.Register(typeof(IHubActivator),
() => new SignalHubActivator(container));
GlobalHost.DependencyResolver.Register(typeof(ILoggingService),
container.Resolve<ILoggingService>);
//etc or you could just pass your existing container to the resolver
GlobalHost.DependencyResolver.UseSqlServer(conn);
}
and then in the hub
private ILoggingService LoggingService{ get; set; }
public NotificationHub()
{
LoggingService = GlobalHost.DependencyResolver.Resolve<ILoggingService>();
}
and for completeness
public class SignalHubActivator: IHubActivator
{
private readonly IWindsorContainer _container;
public SignalHubActivator(IWindsorContainer container)
{
_container = container;
}
public IHub Create(HubDescriptor descriptor)
{
var result= _container.Resolve(descriptor.HubType) as IHub;
if (result is Hub)
{
_container.Release(result);
}
return result;
}
}
OLD ANSWER from 2012
I went with the first option of setting our own DependencyResolver
AspNetHost.SetResolver(new SignalResolver(_container));
I can provide SignalResolver if desired but leaving out for readability for now.
Another important note is that the hubs must have an empty constructor so our castle container injects through properties, e.g.
public class NotificationHub : Hub, INotificationHub
{
public INotificationService NotificationService { get; set; }
and the resolver requested
public class SignalResolver : DefaultDependencyResolver
{
private readonly IWindsorContainer _container;
public SignalResolver(IWindsorContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
_container = container;
}
public override object GetService(Type serviceType)
{
return TryGet(serviceType) ?? base.GetService(serviceType);
}
public override IEnumerable<object> GetServices(Type serviceType)
{
return TryGetAll(serviceType).Concat(base.GetServices(serviceType));
}
private object TryGet(Type serviceType)
{
try
{
return _container.Resolve(serviceType);
}
catch (Exception)
{
return null;
}
}
private IEnumerable<object> TryGetAll(Type serviceType)
{
try
{
var array = _container.ResolveAll(serviceType);
return array.Cast<object>().ToList();
}
catch (Exception)
{
return null;
}
}
}
Here's what I ended up doing. First I followed along with the Windsor wiki to get my ASP.NET MVC3 setup. My Global.asax.cs:
private static IWindsorContainer _container;
protected void Application_Start()
{
BootstrapContainer();
RegisterRoutes(RouteTable.Routes);
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
}
protected void Application_End()
{
_container.Dispose();
}
private static void BootstrapContainer()
{
_container = new WindsorContainer().Install(FromAssembly.This());
RouteTable.Routes.MapHubs(new CastleWindsorDependencyResolver(_container));
var controllerFactory = new WindsorControllerFactory(_container.Kernel);
ControllerBuilder.Current.SetControllerFactory(controllerFactory);
}
...
CastleWindsorDependencyResolver came from here
Copied:
public class CastleWindsorDependencyResolver : DefaultDependencyResolver
{
private readonly IWindsorContainer _container;
public CastleWindsorDependencyResolver(IWindsorContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
_container = container;
// perform the lazy registrations
foreach (var c in _lazyRegistrations)
_container.Register(c);
_lazyRegistrations.Clear();
}
public override object GetService(Type serviceType)
{
if (_container.Kernel.HasComponent(serviceType))
return _container.Resolve(serviceType);
return base.GetService(serviceType);
}
public override IEnumerable<object> GetServices(Type serviceType)
{
IEnumerable<object> objects;
if (_container.Kernel.HasComponent(serviceType))
objects = _container.ResolveAll(serviceType).Cast<object>();
else
objects = new object[] { };
var originalContainerServices = base.GetServices(serviceType);
if (originalContainerServices != null)
return objects.Concat(originalContainerServices);
return objects;
}
public override void Register(Type serviceType, Func<object> activator)
{
if (_container != null)
// cannot unregister components in windsor, so we use a trick
_container.Register(Component.For(serviceType).UsingFactoryMethod<object>(activator, true).OverridesExistingRegistration());
else
// lazy registration for when the container is up
_lazyRegistrations.Add(Component.For(serviceType).UsingFactoryMethod<object>(activator));
// register the factory method in the default container too
//base.Register(serviceType, activator);
}
// a form of laxy initialization is actually needed because the DefaultDependencyResolver starts initializing itself immediately
// while we now want to store everything inside CastleWindsor, so the actual registration step have to be postponed until the
// container is available
private List<ComponentRegistration<object>> _lazyRegistrations = new List<ComponentRegistration<object>>();
}
public static class WindsorTrickyExtensions
{
/// <summary>
/// Overrideses the existing registration:
/// to overide an existiong component registration you need to do two things:
/// 1- give it a name.
/// 2- set it as default.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="componentRegistration">The component registration.</param>
/// <returns></returns>
public static ComponentRegistration<T> OverridesExistingRegistration<T>(this ComponentRegistration<T> componentRegistration) where T : class
{
return componentRegistration
.Named(Guid.NewGuid().ToString())
.IsDefault();
}
}
I wasn't sure WTF the HubsInstaller was trying to do from that same project but I made my own which seems to work fine (I am of course open to any suggestions why this could suck):
public class HubsInstallers : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(Classes.FromThisAssembly()
.BasedOn<IHub>()
.LifestyleTransient());
}
}
Also this is for the newer SignalR versions 0.5+
dove answer is fine but it is a bit confusing, adding another more specific answer.
My main goal is this to work:
[HubName("MyHub")]
public class MyHub : Hub
{
public IJobRepository JobRepository { get; }
public MyHub(IJobRepository jobRepository)
{
JobRepository = jobRepository ?? throw new ArgumentNullException(nameof(jobRepository));
}
...
}
Of course what you want is your Hubs to be created for you, they are usually created by SignalR but now that they have some dependencies SignalR cannot create them.
SignalR itself has a Dependency Resolver (in SignalR namespace) which uses to get its own dependencies, you can add stuff to it, but we want Windsor remember?
So we are going to change just how the IHubActivator creates hubs, we are not going to use SignalR's but this one:
public class SignalRHubActivator : IHubActivator
{
private readonly IWindsorContainer _container;
public SignalRHubActivator(IWindsorContainer container)
{
_container = container;
}
public IHub Create(HubDescriptor descriptor)
{
var result = _container.Resolve(descriptor.HubType) as IHub;
if (result is Hub)
{
_container.Release(result);
}
return result;
}
}
To replace this in SignalR container you have to do something like:
// Get an instance of the hub creator (see note below)
var _hubActivator = new SignalRHubActivator(container);
// Get the SignalR's Default Dependency Resolver
var signalRResolver = new Microsoft.AspNet.SignalR.DefaultDependencyResolver();
// Override the IHubActivator service
signalRResolver.Register(typeof(IHubActivator), () => _hubActivator);
// now map SignalR with this configuration
appBuilder.MapSignalR(new HubConfiguration { Resolver = signalRResolver });
And that's it, you should also register all your Hubs with Windsor
container.Register(Classes.FromThisAssembly()
.BasedOn(typeof(Microsoft.AspNet.SignalR.Hub)));
...
container.Register(Component.For<IJobRepository>()).ImplementedBy<JobRepository>());
Note: I registered the SignalRHubActivator as a component too, this is because the Startup class I use receives the activator as a dependency:
container.Register(Component.For<SignalRHubActivator>().
DependsOn(Dependency.OnValue("container", container)));

Castle Windsor IoC in an MVC application

Prepare for a wall of code... It's a long read, but it's as verbose as I can get.
In response to Still lost on Repositories and Decoupling, ASP.NET MVC
I think I am starting to get closer to understanding this all.
I'm trying to get used to using this. Here is what I have so far.
Project
Project.Web (ASP.NET MVC 3.0 RC)
Uses Project.Models
Uses Project.Persistence
Project
Project.Models (Domain Objects)
Membership.Member
Membership.IMembershipProvider
Project
Project.Persistence (Fluent nHibernate)
Uses Project.Models
Uses Castle.Core
Uses Castle.Windsor
Membership.MembershipProvider : IMembershipProvider
I have the following class in Project.Persistence
using Castle.Windsor;
using Castle.MicroKernel.Registration;
using Castle.MicroKernel.SubSystems.Configuration;
namespace Project.Persistence
{
public static class IoC
{
private static IWindsorContainer _container;
public static void Initialize()
{
_container = new WindsorContainer()
.Install(
new Persistence.Containers.Installers.RepositoryInstaller()
);
}
public static T Resolve<T>()
{
return _container.Resolve<T>();
}
}
}
namespace Persistence.Containers.Installers
{
public class RepositoryInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(
Component
.For<Membership.IMembershipProvider>()
.ImplementedBy<Membership.MembershipProvider>()
.LifeStyle.Singleton
);
}
}
}
Now, in Project.Web Global.asax Application_Start, I have the following code.
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
// Register the Windsor Container
Project.Persistence.IoC.Initialize();
}
Now then, in Project.Web.Controllers.MembershipController I have the following code.
[HttpPost]
public ActionResult Register( Web.Models.Authentication.Registration model)
{
if (ModelState.IsValid)
{
var provider = IoC.Resolve<Membership.IMembershipProvider>();
provider.CreateUser(model.Email, model.Password);
}
// If we got this far, something failed, redisplay form
return View(model);
}
So I am asking first of all..
Am I on the right track?
How can I use Castle.Windsor for my ISessionFactory
I have my SessionFactory working like this ...
namespace Project.Persistence.Factories
{
public sealed class SessionFactoryContainer
{
private static readonly ISessionFactory _instance = CreateSessionFactory();
static SessionFactoryContainer()
{
}
public static ISessionFactory Instance
{
get { return _instance; }
}
private static ISessionFactory CreateSessionFactory()
{
return Persistence.SessionFactory.Map(#"Data Source=.\SQLEXPRESS;Initial Catalog=FluentExample;Integrated Security=true", true);
}
}
}
namespace Project.Persistence
{
public static class SessionFactory
{
public static ISessionFactory Map(string connectionString, bool createSchema)
{
return FluentNHibernate.Cfg.Fluently.Configure()
.Database(FluentNHibernate.Cfg.Db.MsSqlConfiguration.MsSql2008
.ConnectionString(c => c.Is(connectionString)))
.ExposeConfiguration(config =>
{
new NHibernate.Tool.hbm2ddl.SchemaExport(config)
.SetOutputFile("Output.sql")
.Create(/* Output to console */ false, /* Execute script against database */ createSchema);
})
.Mappings(m =>
{
m.FluentMappings.Conventions.Setup(x =>
{
x.AddFromAssemblyOf<Program>();
x.Add(FluentNHibernate.Conventions.Helpers.AutoImport.Never());
});
m.FluentMappings.AddFromAssemblyOf<Mapping.MembershipMap>();
}).BuildSessionFactory();
}
So basically, within my Project.Persistence layer, I call the SessionFactory like this..
var session = SessionFactoryContainer.Instance.OpenSession()
Am I even getting close to doing this right? I'm still confused - I feel like the ISessionFactory should be part of Castle.Windsor, but I can't seem to figure out how to do that. I'm confused also about the way I am creating the Repository in the Controller. Does this mean I have to do all of the 'mapping' each time I use the Repository? That seems like it would be very resource intensive.
Firstly some conceptual details. In an ASP.NET MVC application the typical entry point for a page request is a controller. We want the Inversion of Control container to resolve our controllers for us, because then any dependencies that the controllers have can also be automatically resolved simply by listing the dependencies as arguments in the controllers' constructors.
Confused yet? Here's an example of how you'd use IoC, after it is all set up. I think explaining it this way makes things easier!
public class HomeController : Controller
{
// lets say your home page controller depends upon two providers
private readonly IMembershipProvider membershipProvider;
private readonly IBlogProvider blogProvider;
// constructor, with the dependencies being passed in as arguments
public HomeController(
IMembershipProvider membershipProvider,
IBlogProvider blogProvider)
{
this.membershipProvider = membershipProvider;
this.blogProvider = blogProvider;
}
// so taking your Registration example...
[HttpPost]
public ActionResult Register( Web.Models.Authentication.Registration model)
{
if (ModelState.IsValid)
{
this.membershipProvider.CreateUser(model.Email, model.Password);
}
// If we got this far, something failed, redisplay form
return View(model);
}
}
Note that you have not had to do any resolving yourself, you have just specified in the controller what the dependencies are. Nor have you actually given any indication of how the dependencies are implemented - it's all decoupled. It's very simple there is nothing complicated here :-)
Hopefully at this point you are asking, "but how does the constructor get instantiated?" This is where we start to set up your Castle container, and we do this entirely in the MVC Web project (not Persistence or Domain). Edit the Global.asax file, setting Castle Windsor to act as the controller factory:
protected void Application_Start()
{
//...
ControllerBuilder.Current
.SetControllerFactory(typeof(WindsorControllerFactory));
}
...and define the WindsorControllerFactory so that your controllers are instantiated by Windsor:
/// Use Castle Windsor to create controllers and provide DI
public class WindsorControllerFactory : DefaultControllerFactory
{
private readonly IWindsorContainer container;
public WindsorControllerFactory()
{
container = ContainerFactory.Current();
}
protected override IController GetControllerInstance(
RequestContext requestContext,
Type controllerType)
{
return (IController)container.Resolve(controllerType);
}
}
The ContainerFactory.Current() method is static singleton that returns a configured Castle Windsor container. The configuration of the container instructs Windsor on how to resolve your application's dependencies. So for example, you might have a container configured to resolve the NHibernate SessionFactory, and your IMembershipProvider.
I like to configure my Castle container using several "installers". Each installer is responsible for a different type of dependency, so I'd have a Controller installer, an NHibernate installer, a Provider installer for example.
Firstly we have the ContainerFactory:
public class ContainerFactory
{
private static IWindsorContainer container;
private static readonly object SyncObject = new object();
public static IWindsorContainer Current()
{
if (container == null)
{
lock (SyncObject)
{
if (container == null)
{
container = new WindsorContainer();
container.Install(new ControllerInstaller());
container.Install(new NHibernateInstaller());
container.Install(new ProviderInstaller());
}
}
}
return container;
}
}
...and then we need each of the installers. The ControllerInstaller first:
public class ControllerInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(
AllTypes
.FromAssembly(Assembly.GetExecutingAssembly())
.BasedOn<IController>()
.Configure(c => c.Named(
c.Implementation.Name.ToLowerInvariant()).LifeStyle.PerWebRequest));
}
}
... and here is my NHibernateInstaller although it is different to yours, you can use your own configuration. Note that I'm reusing the same ISessionFactory instance every time one is resolved:
public class NHibernateInstaller : IWindsorInstaller
{
private static ISessionFactory factory;
private static readonly object SyncObject = new object();
public void Install(IWindsorContainer container, IConfigurationStore store)
{
var windsorContainer = container.Register(
Component.For<ISessionFactory>()
.UsingFactoryMethod(SessionFactoryFactory));
}
private static ISessionFactory SessionFactoryFactory()
{
if (factory == null)
{
lock (SyncObject)
{
if (factory == null)
{
var cfg = new Configuration();
factory = cfg.Configure().BuildSessionFactory();
}
}
}
return factory;
}
}
And finally you'll want to define your ProvidersInstaller:
public class ProvidersInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
var windsorContainer = container
.Register(
Component
.For<IMembershipProvider>()
.ImplementedBy<SubjectQueries>())
.Register(
Component
.For<IBlogProvider>()
.ImplementedBy<SubjectQueries>());
// ... and any more that your need to register
}
}
This should be enough code to get going! Hopefully you're still with me as the beauty of the Castle container becomes apparent very shortly.
When you define your implementation of your IMembershipProvider in your persistence layer, remember that it has a dependency on the NHibernate ISessionFactory. All you need to do is this:
public class NHMembershipProvider : IMembershipProvider
{
private readonly ISessionFactory sessionFactory;
public NHMembershipProvider(ISessionFactory sessionFactory)
{
this.sessionFactory = sessionFactory;
}
}
Note that because Castle Windsor is creating your controllers and the providers passed to your controller constructor, the provider is automatically being passed the ISessionFactory implementation configured in your Windsor container!
You never have to worry about instantiating any dependencies again. Your container does it all automatically for you.
Finally, note that the IMembershipProvider should be defined as part of your domain, as it is defining the interface for how your domain behaviours. As noted above, the implementation of your domain interfaces which deal with databases are added to the persistence layer.
Avoid using a static IoC class like this. By doing this you're using the container as a service locator, so you won't achieve the full decoupling of inversion of control. See this article for further explanations about this.
Also check out Sharp Architecture, which has best practices for ASP.NET MVC, NHibernate and Windsor.
If you have doubts about the lifecycle of the container itself, see Usage of IoC Containers; specifically Windsor

Resources