asp.net mvcwebapiのアクションにカスタムAuthorizeAttributeがあります。EFObjectContextを注入する必要があります。
開発サーバーが起動した後の最初のリクエストは常に機能します。失敗するのは次のとおりです。ObjectContextは破棄され、私の一生の間、すべての要求に対していまいましいものを注入する方法を理解できません。
これが私のFilterProviderです。
public class UnityFilterAttributeFilterProvider : IFilterProvider
{
public UnityFilterAttributeFilterProvider(IUnityContainer container)
{
_container = container;
}
private IUnityContainer _container;
public IEnumerable<Filter> GetFilters(HttpConfiguration configuration, HttpActionDescriptor actionDescriptor)
{
if (configuration == null)
{
throw Error.ArgumentNull("configuration");
}
if (actionDescriptor == null)
{
throw Error.ArgumentNull("actionDescriptor");
}
IEnumerable<Filter> first =
actionDescriptor.ControllerDescriptor.ControllerType.GetCustomAttributes(true)
.Select(instance => new Filter((IFilter)instance, FilterScope.Controller));
IEnumerable<Filter> second =
from instance in actionDescriptor.GetFilters()
select new Filter(instance, FilterScope.Action);
foreach (var filter in first.Concat(second))
{
if (filter.Instance is HeroineAuthorizeAttribute)
_container.BuildUp(filter.Instance as HeroineAuthorizeAttribute);
}
return first.Concat(second);
}
}
_container.BuildUpは最初のリクエストで呼び出されますが、後続のリクエストでは呼び出されません。
それがうまくいかなかったとき、私はApiControllerActionInvokerで2倍になりました。ここにあります:
public class InjectingActionInvoker : ApiControllerActionInvoker
{
private readonly IUnityContainer _container;
public InjectingActionInvoker(IUnityContainer container)
{
_container = container;
}
public override System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> InvokeActionAsync(HttpActionContext actionContext, System.Threading.CancellationToken cancellationToken)
{
foreach (var filter in actionContext.ActionDescriptor.GetFilters())
{
if (filter is HeroineAuthorizeAttribute)
{
var f = filter as HeroineAuthorizeAttribute;
f.UserRepository = _container.Resolve<IUserRepository>();
}
}
return base.InvokeActionAsync(actionContext, cancellationToken);
}
}
案の定、インジェクションは、後続のリクエストではなく、最初のリクエストで行われます。ただし、これはすべてOnAuthorizationが呼び出された後に行われるため、あまり意味がありません。とにかく言及したいと思いました。
うーん...では、どうすればこれを行うことができますか?
Application_startも表示すると思いました。空白を埋めることができると確信しています。
var container = CoinUnityContainerFactory.GetUnityContainer();
DependencyResolver.SetResolver(new HeroineDependencyResolver(container));
GlobalConfiguration.Configuration.ServiceResolver.SetResolver(new HeroineServiceResolver(container));