【发布时间】:2015-03-23 19:34:47
【问题描述】:
我正在使用一个在类中具有如下属性的代码示例(它使用 StructureMap 进行 DI):
public Func<IUnitOfWork> UnitOfWorkFactory { get; set; }
按照 Simple Injector 教程,我最终得到了以下代码,它应该会执行属性注入:
public class DependencyAttributeSelectionBehaviour : IPropertySelectionBehavior
{
public bool SelectProperty(Type type, PropertyInfo prop)
{
return prop.GetCustomAttributes(typeof(Dependency)).Any();
}
}
public class Dependency: Attribute
{
// dummy class
}
Global.asax 内部
var container = new Container();
container.Options.PropertySelectionBehavior = new DependencyAttributeSelectionBehaviour();
然后我继续将房产装饰为:
[Dependency]
public Func<IUnitOfWork> UnitOfWorkFactory { get; set; }
但是当UnitOfWorkFactory() 被调用时,我仍然得到一个空异常。
依赖和全局属性在 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());
这是有道理的,因为属性注入不会神奇地为我的函数属性定义一个主体,但我不知道如何实现这一点。任何想法/提示都表示赞赏。
编辑:
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();
}
}
}
【问题讨论】:
-
我试图重现这个,但我没有成功。如果我使用您的代码,容器会抛出“无法注入名称为 'UnitOfWorkFactory' 的 Func
类型的属性,因为找不到 Func 类型的注册。”当我尝试解析包含该属性的对象时。您能否更新您的问题并展示您的问题的完整工作示例? -
@Steven 所以你抓住了我:) 所以我们开始吧,然后我提供了更多细节你还需要什么?我所要做的就是用一个实例初始化该属性,但我没有尝试过任何工作,所以我没有想法..
-
试试这个
container.Register<Func<IFoo>>(() => container.GetInstance<IFoo>(), "UnitOfWorkFactory"); -
@Aron 我试过了:
container.Register<Func<IUnitOfWork>>(() => container.GetInstance<IUnitOfWork>(), "UnitOfWorkFactory");我得到了:Cannot implicitly convert type 'TipsBackend.Models.UnitOfWork.IUnitOfWork' to 'System.Func<TipsBackend.Models.UnitOfWork.IUnitOfWork>' -
@Cemre 我不相信你说你明确键入了通用的 Register 方法。
标签: c# asp.net-web-api2 simple-injector