"The type IUnitOfWork does not have an accessible constructor" with Umbraco 6.1, UmbracoApiController (Web API) & Dependency Injection (Unity) - asp.net-web-api

I am using Umbraco 6.1 with an UmbracoApiController which has a IUnitOfWork injected into it's constructor. To inject the dependencies, I am using Unity, like I have in the past with standard Web API projects. Normally, I set unity up in the Global.asax.cs. As Umbraco does not have this I have created my own UmbracoEvents handler, which inherits from IApplicationEventHandler, and has the methods:
OnApplicationInitialized
OnApplicationStarting
OnApplicationStarted
ConfigureApi
In the OnApplicationStarted method I set up my EF database, db initializer etc and call ConfigureApi to set up Unity. My OnApplication Started and ConfigureApi methods looks like this:
public void OnApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
_applicationContext = applicationContext;
_umbracoApplication = umbracoApplication;
_contentService = ApplicationContext.Current.Services.ContentService;
this.ConfigureApi(GlobalConfiguration.Configuration);
Database.SetInitializer(null);
PropertySearchContext db = new PropertySearchContext();
db.Database.Initialize(true);
}
private void ConfigureApi(HttpConfiguration config)
{
var unity = new UnityContainer();
unity.RegisterType<PropertiesApiController>();
unity.RegisterType<IUnitOfWork, UnitOfWork>(new HierarchicalLifetimeManager());
config.DependencyResolver = new IoCContainer(unity);
}
My Controller code:
public class PropertiesApiController : UmbracoApiController
{
private readonly IUnitOfWork _unitOfWork;
public PropertiesApiController(IUnitOfWork unitOfWork)
{
if(null == unitOfWork)
throw new ArgumentNullException();
_unitOfWork = unitOfWork;
}
public IEnumerable GetAllProperties()
{
return new[] {"Table", "Chair", "Desk", "Computer", "Beer fridge"};
}
}
My Scope Container/IoC Container code: (as per http://www.asp.net/web-api/overview/extensibility/using-the-web-api-dependency-resolver)
public class ScopeContainer : IDependencyScope
{
protected IUnityContainer container;
public ScopeContainer(IUnityContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
this.container = container;
}
public object GetService(Type serviceType)
{
if (container.IsRegistered(serviceType))
{
return container.Resolve(serviceType);
}
else
{
return null;
}
}
public IEnumerable<object> GetServices(Type serviceType)
{
if (container.IsRegistered(serviceType))
{
return container.ResolveAll(serviceType);
}
else
{
return new List<object>();
}
}
public void Dispose()
{
container.Dispose();
}
}
public class IoCContainer : ScopeContainer, IDependencyResolver
{
public IoCContainer(IUnityContainer container)
: base(container)
{
}
public IDependencyScope BeginScope()
{
var child = this.container.CreateChildContainer();
return new ScopeContainer(child);
}
}
My IUnitOfWork code:
public interface IUnitOfWork : IDisposable
{
GenericRepository<Office> OfficeRepository { get; }
GenericRepository<Property> PropertyRepository { get; }
void Save();
void Dispose(bool disposing);
void Dispose();
}
My UnitOfWork implementation:
public class UnitOfWork : IUnitOfWork
{
private readonly PropertySearchContext _context = new PropertySearchContext();
private GenericRepository<Office> _officeRepository;
private GenericRepository<Property> _propertyRepository;
public GenericRepository<Office> OfficeRepository
{
get
{
if (this._officeRepository == null)
{
this._officeRepository = new GenericRepository<Office>(_context);
}
return _officeRepository;
}
}
public GenericRepository<Property> PropertyRepository
{
get
{
if (this._propertyRepository == null)
{
this._propertyRepository = new GenericRepository<Property>(_context);
}
return _propertyRepository;
}
}
public void Save()
{
_context.SaveChanges();
}
private bool disposed = false;
public virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
_context.Dispose();
}
}
this.disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
I have used unity/DI with MVC4/WebAPI controllers and this implementation of UnitOfWork many times before without issue, so I'm thinking it's Umbraco specific.
I have also debugged the application and made sure that it hits OnApplicationStarted and that its parameters are not null.
The GetAllProperties method in the controller is just a test method to make sure it is all working fine, however, when I try and access this action I get the error:
"The type IUnitOfWork does not have an accessible constructor"
Does anyone have experience with using Umbraco 6.1 and it's UmbracoApiController with dependency injection/Unity?
Also, on an unrelated note, is there a way to return JSON instead of XML in the action? In Web API you would just define the formatter in the WebApi.config but there is none in Umbraco.
Thanks,
Justin

In case you haven't found a solution to your problem? Download this nuget package and right after building your unity container:
GlobalConfiguration.Configuration.DependencyResolver =
new Unity.WebApi.UnityDependencyResolver(Bootstrapper.Container);
Notice the namespace which is different than Unity.Mvc4.UnityDependencyResolver.

Related

Confused about using dispose in my repository. EF6 MVC

I have been trying to implement a repository pattern in my project. I am not sure if i am using dispose correctly. I took the pattern from the MVA course on entity framework.
My repository
public static bool IsAwesome { get { return true; } }
public class Repository<T> : IDisposable where T : class
{
private ApplicationDbContext db = null;
protected DbSet<T> DbSet { get; set; }
public Repository()
{
db = new ApplicationDbContext();
DbSet = db.Set<T>();
}
public List<T> GetAll()
{
return DbSet.ToList();
}
public T Get(int id)
{
return DbSet.Find(id);
}
public T GetWithString(string id)
{
return DbSet.Find(id);
}
public void Add(T entity)
{
DbSet.Add(entity);
}
public void Update(T entity)
{
DbSet.Attach(entity);
db.Entry(entity);
}
public void SaveChanges()
{
db.SaveChanges();
}
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
db.Dispose();
}
}
this.disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
Example of imageRepository which inherits from repository
public class ImageRepository : Repository<Image>
{
public Image GetLatest(int vehicleId)
{
return DbSet.FirstOrDefault(p => p.VehicleId == vehicleId);
}
public List<Image> GetImagesByVehicleId(int vehicleId)
{
return DbSet.Where(p => p.VehicleId == vehicleId).ToList();
}
}
Using my repository on top of the controller and disposing in the bottom of my controller
ImageRepository imageRepository = new ImageRepository();
UserRepository userRepository = new UserRepository();
protected override void Dispose(bool disposing)
{
imageRepository.Dispose();
userRepository.Dispose();
base.Dispose(disposing);
}
Will my code handle all unmanaged connections and close them correctly?
Thank you in advance. Im still a bit new to MVC and EF. I am sorry if my question is a bit newbish. My first post in here. So i hope i did not break any rules:)
Add your Dispose code in UnitOfWork,Remove From GenericRepository
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
Context.Dispose();
}
}
this.disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
Will my code handle all unmanaged connections and close them
correctly?
Apparently yes.
However, you are not quite following the pattern. You don't have to SuppressFinalize as you don't have a finalizer in your class.Have a read about proper implementation of IDisposable Pattern.

Ninject Interception in WebAPI and parameterless constructor failing

I have an MVC4 site that uses both MVC and WebAPI in it. All was going well till I tried to change my classes to have a cross cutting AOP class that would help with caching data. I am now finding that when I call a method that does not have the InterceptAttribute on it, it will crash because Ninject didn't inject with a parameter, and it fails.
My BLL class looks like this:
public class FooBLL
{
#region Private Variables
private readonly IDAL _context;
#endregion
#region Constructor
public Foo(IDAL context)
{
_context = context;
}
#endregion
#region Public Methods
public List<Bar> GetAllBars()
{
return _context.GetAllBars();
}
public List<Bar> GetTwoBars()
{
return _context.GetTwoBars();
}
#endregion
}
My WebApi Controller looks like this:
public class FooController : ApiController
{
#region Private Variables
private readonly FooBLL _fooBll;
#endregion
#region Constructor
public FooController(FooBLL fooBll)
{
_fooBll = fooBll;
}
#endregion
#region Public Methods
#region Estimate Types
#region Get
public List<Bar> GetAllBars()
{
return _fooBll.GetAllBars();
}
public List<Bar> GetTwoBars()
{
return _fooBll.GetTwoBars();
}
#endregion
#endregion
#endregion
}
In my Website, I created the following Ninject classes for resolving the controllers:
public class NinjectRegistrations : NinjectModule
{
public override void Load()
{
Kernel.Bind<IDAL>().To<DAL>().InSingletonScope();
}
}
public class NinjectDependencyResolver : NinjectDependencyScope, IDependencyResolver, System.Web.Mvc.IDependencyResolver
{
private readonly IKernel kernel;
public NinjectDependencyResolver(IKernel kernel)
: base(kernel)
{
this.kernel = kernel;
}
public IDependencyScope BeginScope()
{
return new NinjectDependencyScope(this.kernel.BeginBlock());
}
}
public class NinjectDependencyScope : IDependencyScope
{
private IResolutionRoot resolver;
internal NinjectDependencyScope(IResolutionRoot resolver)
{
Contract.Assert(resolver != null);
this.resolver = resolver;
}
public void Dispose()
{
var disposable = this.resolver as IDisposable;
if (disposable != null)
{
disposable.Dispose();
}
this.resolver = null;
}
public object GetService(Type serviceType)
{
if (this.resolver == null)
{
throw new ObjectDisposedException("this", "This scope has already been disposed");
}
return this.resolver.TryGet(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
if (this.resolver == null)
{
throw new ObjectDisposedException("this", "This scope has already been disposed");
}
return this.resolver.GetAll(serviceType);
}
}
In Global.asax I then register this resolver:
NinjectHelper.Kernel = new StandardKernel(modules);
var ninjectResolver = new NinjectDependencyResolver(NinjectHelper.Kernel);
DependencyResolver.SetResolver(ninjectResolver); // MVC
GlobalConfiguration.Configuration.DependencyResolver = ninjectResolver; // Web API
//Register Filter Injector
GlobalConfiguration.Configuration.Services.Add(typeof(System.Web.Http.Filters.IFilterProvider), new NinjectWebApiFilterProvider(NinjectHelper.Kernel));
Things were fine till I added the attribute Cache using Ninject.Extensions.Interception.Attributes.InterceptAttribute.
The class now looks like this (note that I added a parameterless constructor and marked one of the methods as virtual, these are both required for the Interception to work):
public class FooBLL
{
#region Private Variables
private readonly IDAL _context;
#endregion
#region Constructor
public Foo(IDAL context)
{
_context = context;
}
public Foo()
{
}
#endregion
#region Public Methods
public List<Bar> GetAllBars()
{
return _context.GetAllBars();
}
[Cache(DefaultTimeoutMinutes = 20)]
public virtual List<Bar> GetTwoBars()
{
return _context.GetTwoBars();
}
#endregion
}
Now on the WebAPI controller, when I call GetToBars(the method with the Intercept Attribute), everything still works fine.
However, when I call GetAllBars(the method that doesn't have the Intercept Attribute), I fail with an exception that _context is null.
Any help would be greatly appreciated.
Ben

SignalR + Dependency Injection Questions

I am using SignalR in my MVC3 application, and since I have implemented StructureMap Dependency Injection on my controllers I would like to do the same in my hub, but I can't seem to get it working.
Please tell me what's wrong with my codes below:
SignalRSmDependencyResolver.cs
public class SignalRSmDependencyResolver : DefaultDependencyResolver
{
private IContainer _container;
public SignalRSmDependencyResolver(IContainer container)
{
_container = container;
}
public override object GetService(Type serviceType)
{
object service = null;
if (!serviceType.IsAbstract && !serviceType.IsInterface && serviceType.IsClass)
{
// Concrete type resolution
service = _container.GetInstance(serviceType);
}
else
{
// Other type resolution with base fallback
service = _container.TryGetInstance(serviceType) ?? base.GetService(serviceType);
}
return service;
}
public override IEnumerable<object> GetServices(Type serviceType)
{
var objects = _container.GetAllInstances(serviceType).Cast<object>();
objects.Concat(base.GetServices(serviceType));
return objects;
}
}
SignalRExtensionsRegistry.cs
public class SignalRExtensionsRegistry : Registry
{
public SignalRExtensionsRegistry()
{
For<IDependencyResolver>().Add<SignalRSmDependencyResolver>();
}
}
IoC.cs
public static class IoC {
public static IContainer Initialize() {
var container = BootStrapper.Initialize();
container.Configure(x =>
{
x.For<IControllerActivator>().Singleton().Use<StructureMapControllerActivator>();
});
return container;
}
}
public class StructureMapControllerActivator : IControllerActivator {
public StructureMapControllerActivator(IContainer container) {
_container = container;
}
private IContainer _container;
public IController Create(RequestContext requestContext, Type controllerType) {
IController controller = DependencyResolver.Current.GetService(controllerType) as IController;
return controller;
}
}
AppStart_Structuremap.cs
[assembly: WebActivator.PreApplicationStartMethod(typeof(StoreUI.AppStart_Structuremap), "Start")]
namespace MyNameSpace {
public static class AppStart_Structuremap {
public static void Start() {
var container = (IContainer) IoC.Initialize();
DependencyResolver.SetResolver(new StructureMapDependenceyResolver(container));
AspNetHost.SetResolver(new StructureMapDependencyResolver(container));
}
}
}
NotificationsHub.cs
[HubName("notificationsHub")]
public class NotificationsHub : Hub
{
#region Declarations
private readonly IUserService userService;
#endregion
#region Constructor
public NotificationsHub(IUserService userService)
{
this.userService = userService;
}
#endregion
public void updateServer(string message)
{
Clients.updateClient(message);
}
}
Thanks
Getting Structuremap into SignalR is actually pretty easy. First you want to create your own resolver:
StructureMap Resolver
Usings:
using SignalR.Infrastructure;
using StructureMap;
Class:
public class StructureMapResolver : DefaultDependencyResolver
{
private IContainer _container;
public StructureMapResolver(IContainer container)
{
_container = container;
}
public override object GetService(Type serviceType)
{
object service = null;
if (!serviceType.IsAbstract && !serviceType.IsInterface && serviceType.IsClass)
{
// Concrete type resolution
service = _container.GetInstance(serviceType);
}
else
{
// Other type resolution with base fallback
service = _container.TryGetInstance(serviceType) ?? base.GetService(serviceType);
}
return service;
}
public override IEnumerable<object> GetServices(Type serviceType)
{
var objects = _container.GetAllInstances(serviceType).Cast<object>();
return objects.Concat(base.GetServices(serviceType));
}
}
The idea here is to try and use your container to resolve the dependencies, if you do not have the dependency wired up, pass it through to the default resolver. This way you don't have to worry about all of the other dependencies in SignalR and can focus only on the stuff you want to inject into (Hubs, ConnectionIdFactory, MessageBus, etc.).
Bindings for Resolver and Hub
Next you will want to register this in your container (i like using registries):
Usings:
using SignalR.Infrastructure;
using StructureMap.Configuration.DSL;
Class:
public class ExtensionsRegistry : Registry
{
public ExtensionsRegistry()
{
For<IDependencyResolver>().Add<StructureMapResolver>();
}
}
Resolver Replacement
Finally you will want to tell SignalR to use your resolver instead of the default:
Global::Application_Start or WebActivator::Pre_Start
Usings:
using SignalR.Hosting.AspNet;
using SignalR.Infrastructure;
Application_Start:
// Make sure you build up the container first
AspNetHost.SetResolver(StructureMap.ObjectFactory.GetInstance<IDependencyResolver>());
Silly Hub with injected dependencies
Now you can just inject any dependencies your container knows about into the hubs themselves:
[HubName("defaultHub")]
public class DefaultHub : Hub, IDisconnect
{
private readonly IRepository _repo;
public DefaultHub(IRepository repo)
{
_repo = repo;
}
public void Connect()
{
Caller.setUser(Context.ConnectionId);
Clients.addMessage(string.Format("{0} has connected", Context.ConnectionId));
}
public void MessageSender(string message)
{
Caller.addMessage(_repo.RepositoryMessage());
Clients.addMessage(message);
}
public Task Disconnect()
{
var clientId = this.Context.ConnectionId;
return Task.Factory.StartNew(() => { Clients.addMessage(string.Format("{0} has disconnected", clientId)); });
}
}
Have you followed the instructions here:- https://github.com/SignalR/SignalR/wiki/Extensibility ?
You'll need to use AspNetHost.SetResolver.
I know this is an old thread, but for those who are wondering where is the AspNetHost.SetResolver in the newer version of signalR, you can use this in the App_Start StructuremapMvc.cs:
public static void Start() {
IContainer container = IoC.Initialize();
GlobalHost.DependencyResolver = new SignalRSmDependencyResolver(container); // for signalR
DependencyResolver.SetResolver(new StructureMapDependencyResolver(container));
GlobalConfiguration.Configuration.DependencyResolver = new StructureMapDependencyResolver(container);
}
Add something like this to a file in your App_Start folder. This code snippet is for Ninject, so just replace AspNetHost.SetResolver()
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using Ninject;
using SignalR.Hosting.AspNet;
using SignalR.Infrastructure;
using SignalR.Ninject;
using Web.Models;
[assembly: WebActivator.PreApplicationStartMethod(typeof(Web.App_Start.NinjectSignalR), "Start")]
namespace Web.App_Start
{
public static class NinjectSignalR
{
public static void Start()
{
IKernel kernel = CreateKernel();
// switch this line to the structuremap resolver
AspNetHost.SetResolver(new NinjectDependencyResolver(kernel));
}
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
RegisterServices(kernel);
return kernel;
}
private static void RegisterServices(IKernel kernel)
{
// add your services here
//kernel.Bind<IRepository>().To<Repository>();
}
}
}

How should the GetService method in IDependencyResolver implementation for Unity look like?

I'd like to use Unity as an IoC container for an ASP.NET MVC 3 app but am having trouble with my UnityDependecyResolver class. It currently looks like this (copied from somewhere on the web as I don't think Unity itself comes with this):
public class UnityDependencyResolver : IDependencyResolver
{
readonly IUnityContainer _container;
public UnityDependencyResolver(IUnityContainer container)
{
this._container = container;
}
public object GetService(Type serviceType)
{
try
{
return _container.Resolve(serviceType);
}
catch
{
return null;
}
}
public IEnumerable<object> GetServices(Type serviceType)
{
try
{
return _container.ResolveAll(serviceType);
}
catch
{
return new List<object>();
}
}
}
However, I get this runtime error when trying to visit any controller:
The IControllerFactory 'System.Web.Mvc.DefaultControllerFactory' did not return a controller for the name 'Account'.
This StructureMap article suggests that I should amend the GetService method, however, I'm quite new to both MVC and Unity and I'm not sure how exactly should it look like.
Have a look at the Unity.MVC project on codeplex.
This is my implementation and for me it works
public class UnityResolver : IDependencyResolver
{
private readonly IUnityContainer _container;
public UnityResolver(IUnityContainer container)
{
_container = container;
}
public object GetService(Type serviceType)
{
if (typeof(IController).IsAssignableFrom(serviceType))
{
return _container.CreateChildContainer().Resolve(serviceType);
}
if (_container.IsRegistered(serviceType))
{
return _container.CreateChildContainer().Resolve(serviceType);
}
return null;
}
public IEnumerable<object> GetServices(Type serviceType)
{
return _container.CreateChildContainer().ResolveAll(serviceType);
}
}

MVC3, Unity Framework and Per Session Lifetime Manager Issue

In a simple word I try to create Lifetime manager for Unity framework by using Http Session in my MVC3 project. My sample implementation of lifetime manager is:
public class UnityPerSessionLifetimeManager : LifetimeManager
{
private string sessionKey;
private HttpContext ctx;
public UnityPerSessionLifetimeManager(string sessionKey)
{
this.sessionKey = sessionKey;
this.ctx = HttpContext.Current;
}
public override object GetValue()
{
return this.ctx.Session[this.sessionKey];
}
public override void RemoveValue()
{
this.ctx.Items.Remove(this.sessionKey);
}
public override void SetValue(object newValue)
{
this.ctx.Session[this.sessionKey] = newValue;
}
}
In my global.asax.cs I replaced default controller factory with my own UnityControllerFactory
public class UnityControllerFactory : DefaultControllerFactory
{
private IUnityContainer container;
public UnityControllerFactory(IUnityContainer container)
{
this.container = container;
this.RegisterServices();
}
protected override IController GetControllerInstance(RequestContext context, Type controllerType)
{
if (controllerType != null)
{
return this.container.Resolve(controllerType) as IController;
}
return null;
}
private void RegisterServices()
{
this.container.RegisterType<IMyType, MyImpl>(new UnityPerSessionLifetimeManager("SomeKey"));
}
}
}
I set breakpoints on each function of UnityPerSessionLifetimeManager class, I noticed that when controller factory tries to solve dependencies of my controller, the HttpContext.Session is actually null, so the code fails retrieve from session or save to session.
Any idea why session is null at this stage?
My mistake, I should change code of UnityPerSessionLifetimeManager class to be
public class UnityPerSessionLifetimeManager : LifetimeManager
{
private string sessionKey;
public UnityPerSessionLifetimeManager(string sessionKey)
{
this.sessionKey = sessionKey;
}
public override object GetValue()
{
return HttpContext.Current.Session[this.sessionKey];
}
public override void RemoveValue()
{
HttpContext.Current.Session.Remove(this.sessionKey);
}
public override void SetValue(object newValue)
{
HttpContext.Current.Session[this.sessionKey] = newValue;
}
}
because when the constructor was called to register type, session state is not ready yet and I already assigned http context of that time to a variable. But in later Get/Set functions session state is ready.

Resources