How to use property injection in unity and asp.net mvc3? - asp.net-mvc-3

I would like to use property injection in an MVC3 application. I have configured Unity 2 as a DI container and everything works just fine by constructor injection but I can't figure out how to use property injection. I marked properties with the [Dependency] attribute but it doesn't work.
public class UnityDependencyResolver : IDependencyResolver
{
IUnityContainer _container;
public UnityDependencyResolver(IUnityContainer container)
{
_container = container;
}
public object GetService(Type serviceType)
{
try
{
return _container.Resolve(serviceType);
}
catch (Exception)
{
return null;
}
}
public IEnumerable<object> GetServices(Type serviceType)
{
try
{
return _container.ResolveAll(serviceType);
}
catch (Exception)
{
return new List<object>();
}
}
}
In Global.asax I have the following:
var container = new UnityContainer();
var section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
section.Configure(container);
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
Any help is appreciated.

Related

WebApi 2 -cant determined DataProtection.IDataProtector Dependency Injection with structuremap

I'm using this beriliant project for base of my MVC project.
But when I use WebAPI for project there is problem in IDataProtector injection.
I redesign base and upload here, and add a console project for testing authorizing with WebAPI.
This is structuremap initialization :
private static readonly Lazy<Container> _containerBuilder =
new Lazy<Container>(initStructureMap, LazyThreadSafetyMode.ExecutionAndPublication);
public static IContainer Container
{
get { return _containerBuilder.Value; }
}
return new Container(ioc =>
{
ioc.For<IUnitOfWork>().HybridHttpOrThreadLocalScoped().Use(() => new DbContext());
ioc.For<IDataSerializer<AuthenticationTicket>>().Use<TicketSerializer>();
ioc.For<ISecureDataFormat<AuthenticationTicket>>().Use<SecureDataFormat<AuthenticationTicket>>();
});
and in WebApiConfig class DI is like this:
var container = StructuremapMvc.Container;
GlobalConfiguration.Configuration.Services.Replace(
typeof(IHttpControllerActivator), new StructureMapHttpControllerActivator(container));
in my startup I create dataprotector with IAppBuilder :
public void ConfigureAuth(IAppBuilder app)
{
StructuremapMvc.Container.Configure(config =>
{
config.For<IDataProtectionProvider>()
.HybridHttpOrThreadLocalScoped()
.Use(() => app.GetDataProtectionProvider());
});
}
It start after WebApiConfig and IDataProtection not work in WebApi. my ServiceLayer is in separate project and DataProtection need to inject there.
you need add two class to your project :
1-StructureMapDependencyScope Class
using StructureMap;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http.Dependencies;
namespace Project.Helpers
{
public class StructureMapDependencyScope : IDependencyScope
{
protected readonly IContainer Container;
public StructureMapDependencyScope(IContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
this.Container = container;
}
public void Dispose()
{
this.Container.Dispose();
}
public object GetService(Type serviceType)
{
if (serviceType == null)
{
return null;
}
try
{
return serviceType.IsAbstract || serviceType.IsInterface
? this.Container.TryGetInstance(serviceType)
: this.Container.GetInstance(serviceType);
}
catch
{
return null;
}
}
public IEnumerable<object> GetServices(Type serviceType)
{
return this.Container.GetAllInstances(serviceType).Cast<object>();
}
}
}
2-StructureMapDependencyResolver Class
using StructureMap;
using System.Web.Http.Dependencies;
namespace Project.Helpers
{
public class StructureMapDependencyResolver : StructureMapDependencyScope, IDependencyResolver
{
public StructureMapDependencyResolver(IContainer container)
: base(container)
{
}
public IDependencyScope BeginScope()
{
IContainer child = this.Container.GetNestedContainer();
return new StructureMapDependencyResolver(child);
}
}
}
at the end replace this code with yours in WebApiConfig Class:
// IoC Config
var container = SmObjectFactory.Container;
// Web API configuration and services
config.DependencyResolver = new StructureMapDependencyResolver(container);
read more about Dependency Injection in ASP.NET MVC 4 and Web API by StructureMap here.
You need to explicitly register implementation of IDataProtector in the container.
Sample configuration might looks like this:
ioc.For<IDataProtector>().Use(() => new DpapiDataProtectionProvider().Create("ASP.NET Identity"));
ioc.For<ITextEncoder>().Use<Base64UrlTextEncoder>();
Bear in mind that this specific configuration might not suit your exact needs.
Hope this helps!

"The type IUnitOfWork does not have an accessible constructor" with Umbraco 6.1, UmbracoApiController (Web API) & Dependency Injection (Unity)

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.

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);
}
}

Resolving MVC Controller with WindsorControllerFactory

I'm new to Windsor, so
Here is my installer:
public class ControllersInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(FindControllers().Configure(ConfigureControllers()));
}
private ConfigureDelegate ConfigureControllers()
{
return c => c.LifeStyle.Transient;
}
private BasedOnDescriptor FindControllers()
{
return AllTypes.FromThisAssembly()
.BasedOn<IController>()
.If(Component.IsInSameNamespaceAs<HomeController>())
.If(t => t.Name.EndsWith("Controller"));
}
}
And factory:
public class WindsorControllerFactory : DefaultControllerFactory
{
private readonly IKernel _kernel;
public WindsorControllerFactory(IKernel kernel)
{
_kernel = kernel;
}
public override void ReleaseController(IController controller)
{
_kernel.ReleaseComponent(controller);
}
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
try
{
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);
}
catch(Exception ex)
{
return null;
}
}
}
All controllers which inherits from Controller are resolved well. But when I try to instantiate something like this:
public class ArticleController : RestController<Article>
{
protected override JsonResult Create(Article item)
{
...
}
}
RestController also inherits from Controller
it throws
The IControllerFactory 'TheStorage.Web.Factories.WindsorControllerFactory' did not return a controller for the name 'Article'
What I'm doing wrong?
The error you're getting is due to the try/catch that you put in the factory. You should not be doing that.
Now, what is happening most likely, is your container can not resolve your controller, likely either because it has unresolvable dependencies, or it doesn't get registered (maybe you put it in wrong namespace)?
Once you let it fail, Windsor will tell you exactly what the problem is.

Constructor DI + Unity 2.0 + issue with resolving dependency

Controller:
public class HomeController : Controller
{
IEmployeeTask _employeeTask;
public HomeController()
{
_employeeTask = new UnityContainer().Resolve<IEmployeeTask>();
}
public HomeController(IEmployeeTask employeeTask)
{
_employeeTask = employeeTask;
}
public ActionResult Index()
{
ViewBag.Message = "Welcome to ASP.NET MVC!";
return View();
}
public ActionResult GetAndDisplayEmployee()
{
return View();
}
[HttpPost]
public ActionResult GetAndDisplayEmployee(int empid)
{
return View(_employeeTask.GetEmployeeModelFromService(empid));
}
}
Global.asax.cs:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
var container = new UnityContainer();
container.RegisterType<IEmployeeModelMap, EmployeeModelMap>();
container.RegisterType<IEmployeeService, EmployeeService>();
container.RegisterType<IEmployeeTask, EmployeeTask>();
container.RegisterType<IEmployee, Employee>();
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
}
Unity Dependency Resolver:
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>();
}
}
}
Employee Task class:
public class EmployeeTask: IEmployeeTask
{
IEmployeeService _employeeService;
IEmployeeModelMap _employeeModelMap;
public EmployeeTask(IEmployeeService employeeService, IEmployeeModelMap employeeModelMap)
{
_employeeService = employeeService;
_employeeModelMap = employeeModelMap;
}
public EmployeeViewModel GetEmployeeModelFromService(int empId)
{
return _employeeModelMap.ToModel(_employeeService.GetEmployeeFromEntities(empId));
}
}
Now, i have used unity 2.0 application block. Tried to resolve the dependency of the controller using unity with out using Custom Controller factory.
I am stuck with below error.
The current type, DataProviderInfrastructure.IEmployeeTask, is an
interface and cannot be constructed. Are you missing a type mapping?
I don't use Unity, but my guess would be that it attempts to use your parameterless constructor where you try to resolve the dependency. Creating this constructor is very very wrong. First - it defeats the purpose of having dependency injection and second - you create new container inside - which will be empty so it obviously can't resolve any dependencies. Try removing this from your code:
public HomeController()
{
_employeeTask = new UnityContainer().Resolve<IEmployeeTask>();
}

Resources