I am using a code sample (which uses StructureMap for DI) that has a property in a class as follows:
public Func<IUnitOfWork> UnitOfWorkFactory { get; set; }
Following Simple Injector tutorial, I ended up with the following code which will supposedly do the property injection:
public class DependencyAttributeSelectionBehaviour : IPropertySelectionBehavior
{
public bool SelectProperty(Type type, PropertyInfo prop)
{
return prop.GetCustomAttributes(typeof(Dependency)).Any();
}
}
public class Dependency: Attribute
{
// dummy class
}
Inside Global.asax
var container = new Container();
container.Options.PropertySelectionBehavior = new DependencyAttributeSelectionBehaviour();
then I go ahead and decorate the property as:
[Dependency]
public Func<IUnitOfWork> UnitOfWorkFactory { get; set; }
However I still get a null exception when UnitOfWorkFactory()
is called.
Dependencies and a global attribute are initialized as follows in Global.asax:
// Create the container as usual.
var container = new Container();
container.Options.PropertySelectionBehavior = new DependencyAttributeSelectionBehaviour();
// Register your types, for instance using the RegisterWebApiRequest
// extension from the integration package:
container.RegisterWebApiRequest<IUnitOfWork, NHibernateUnitOfWork>();
container.RegisterSingle<ISessionSource, NHibernateSessionSource>();
container.RegisterSingle<IAppSettings, AppSettings>();
container.Register(() =>
{
var uow = (INHibernateUnitOfWork) (container.GetInstance<IUnitOfWork>());
return uow.Session;
});
container.Register<IUserRepository, UserRepository>();
// This is an extension method from the integration package.
container.RegisterWebApiControllers(GlobalConfiguration.Configuration);
container.Verify();
GlobalConfiguration.Configuration.DependencyResolver =
new SimpleInjectorWebApiDependencyResolver(container);
GlobalConfiguration.Configuration.Filters.Add(new UnitOfWorkAttribute());
This makes sense since property injection will not magically define a body for my function property but I don't have any idea how else to achieve this. Any ideas/tips are appreciated.
EDIT:
public class UnitOfWorkAttribute : ActionFilterAttribute
{
[Dependency]
private Func<IUnitOfWork> UnitOfWorkFactory { get; set; }
public override void OnActionExecuting(HttpActionContext filterContext)
{
UnitOfWorkFactory().Begin();
}
// TODO: Fix this: We should also probably check if exception is handled
public override void OnActionExecuted(HttpActionExecutedContext filterContext)
{
var uow = UnitOfWorkFactory();
try
{
if (filterContext.Exception != null)
{
uow.Rollback();
}
else
{
uow.Commit();
}
}
catch
{
uow.Rollback();
throw;
}
finally
{
uow.Dispose();
}
}
}