Por el momento, tengo un ControllerFactory personalizado en el que me inyecto mi contenedor Unidad:con Unity para inyectar dependencias en una costumbre ActionFilter
en Application_Start Global.asax():
var container = InitContainer();
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
var factory = new UnityControllerFactory(container);
ControllerBuilder.Current.SetControllerFactory(factory);
En el fábrica de controlador de E puso mis controladores de utilizar una ActionInvoker encargo de este modo:
protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
{
var controller = base.GetControllerInstance(requestContext, controllerType) as Controller;
if (controller != null)
controller.ActionInvoker = new UnityActionInvoker(_container);
return controller;
}
último en mi ActionInvoker personalizada, trato de acciones que se invocan utilizando acumulación de la ActionInvokers contenedor:
protected override ActionExecutedContext InvokeActionMethodWithFilters(
ControllerContext controllerContext,
IList<IActionFilter> filters,
ActionDescriptor actionDescriptor,
IDictionary<string, object> parameters)
{
var builtUpFilters = new List<IActionFilter>();
foreach (IActionFilter actionFilter in filters)
{
builtUpFilters.Add(_container.BuildUp<IActionFilter>(actionFilter));
}
return base.InvokeActionMethodWithFilters(controllerContext, builtUpFilters, actionDescriptor, parameters);
}
Este es un ejemplo de uno de los ActionFilters que se está construyendo:
public class PopulatRolesAttribute : ActionFilterAttribute, IActionFilter
{
private const string RolesKey = "roles";
[Dependency]
public Func<IMetadataService> Service { get; set; }
public PopulatRolesAttribute()
{
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext.Controller.ViewData[RolesKey] == null)
{
filterContext.Controller.ViewData[RolesKey] = Service().GetRoles();
}
}
}
El problema es que la propiedad pública sobre mi costumbre ActionFilterAttribute Nunca se inyecta con cualquier cosa, ¡permanece nulo en la ejecución! No puedo ver por qué mi filtro no está siendo creado correctamente por el contenedor. El tipo que se inyecta se ha registrado correctamente, así:
container.RegisterInstance(new ChannelFactory<IMetadataService>(
new BasicHttpBinding(),
new EndpointAddress("http://example.com/ABSApplication/MetadataService.svc")));
container.RegisterInstance<Func<IMetadataService>>(
() => container.Resolve<ChannelFactory<IMetadataService>>().CreateChannel());
Y también se está inyectando en otra parte de la aplicación (aunque no a través de .Buildup). Este es prácticamente el mismo proceso seguido por este blog post. ¿Qué pieza del rompecabezas me estoy perdiendo?
Por curiosidad, ¿por qué no hacer esto en, por ejemplo, autenticar la solicitud, petición PREAUTH, etc y la memoria caché ellos (la sesión, etc.) por lo que hay para cada solicitud, mientras que el usuario está conectado? –
Mi intención original era encapsular esta funcionalidad para poder agregarla cada vez que una acción lo requiriera. Si después de la revisión usaría los datos recuperados por los filtros en una cantidad significativa, ciertamente los almacenaría en caché globalmente para su reutilización a lo largo de la aplicación. En realidad, está empezando a parecer que sería una solución más fácil de todos modos, independientemente de la reutilización. Todavía tengo curiosidad por saber por qué 'container.BuildUp' no funciona. –
Encontré esta muestra, voy a verla en breve. La fuente también está disponible para su descarga allí http://msdn.microsoft.com/en-us/gg618494 –