Внедрение зависимости фильтра действий в ASP.NET MVC 3 RC2 с помощью StructureMap

Я играл с поддержкой DI в ASP.NET MVC RC2.

Я реализовал сеанс для каждого запроса для NHibernate, и мне нужно ввести ISession в свой Фильтр действий «Единица работы».

Если я напрямую ссылаюсь на контейнер StructureMap (ObjectFactory.GetInstance) или использую DependencyResolver для получения экземпляра сеанса, все работает нормально:

    ISession Session {
        get { return DependencyResolver.Current.GetService<ISession>(); }
    }

Однако, если я попытаюсь использовать мою StructureMap поставщик фильтра (наследует FilterAttributeFilterProvider ) У меня проблемы с фиксацией транзакции NHibernate в конце запроса.

Это как если бы объекты ISession совместно использовались между запросами. Я наблюдаю это часто, поскольку все мои изображения загружаются через контроллер MVC, поэтому я получаю около 20 сеансов NHibernate, созданных при нормальной загрузке страницы.

Я добавил следующее в свой фильтр действий:

    ISession Session {
        get { return DependencyResolver.Current.GetService<ISession>(); }
    }

    public ISession SessionTest { get; set; }

    public override void OnResultExecuted(System.Web.Mvc.ResultExecutedContext filterContext) {

        bool sessionsMatch = (this.Session == this.SessionTest);

SessionTest вводится с использованием StructureMap Filter провайдер.

Я обнаружил, что на странице с 20 изображениями "sessionsMatch" было ложным для 2-3 запросов.

Моя конфигурация StructureMap для управления сеансом выглядит следующим образом:

        For<ISessionFactory>().Singleton().Use(new NHibernateSessionFactory().GetSessionFactory());
        For<ISession>().HttpContextScoped().Use(ctx => ctx.GetInstance<ISessionFactory>().OpenSession());

В global.asax я вызываю следующее в конце каждого запроса:

    public Global() {
        EndRequest += (sender, e) => {
            ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects();
        };
    }

Является ли эта конфигурация потокобезопасной? Раньше я вводил зависимости в один и тот же фильтр с помощью пользовательского IActionInvoker . Это работало нормально до MVC 3 RC2, когда у меня возникла проблема, описанная выше, поэтому я подумал, что попробую использовать вместо этого поставщика фильтров.

Любая помощь будет принята с благодарностью.

Я ' m с использованием NHibernate 3 RC и последней версии StructureMap

Update:

Ниже приведены мои реализации DependencyResolver ​​и FilterAttributeFilterProvider :

    public class StructureMapDependencyResolver : IDependencyResolver {
    private readonly IContainer container;

    public StructureMapDependencyResolver(IContainer container) {
        this.container = container;
    }

    public object GetService(Type serviceType) {
        var instance = container.TryGetInstance(serviceType);
        if (instance==null && !serviceType.IsAbstract){
            instance = AddTypeAndTryGetInstance(serviceType);
        }
        return instance;
    }

    private object AddTypeAndTryGetInstance(Type serviceType) {
        container.Configure(c=>c.AddType(serviceType,serviceType));
        return container.TryGetInstance(serviceType);
    }

    public IEnumerable<object> GetServices(Type serviceType) {
        return container.GetAllInstances(serviceType).Cast<object>();
    }
}
public class StructureMapFilterAttributeFilterProvider : FilterAttributeFilterProvider
{
    private readonly IContainer container;

    public StructureMapFilterAttributeFilterProvider(IContainer container) {
        this.container = container;
    }

    protected override IEnumerable<FilterAttribute> GetControllerAttributes(ControllerContext controllerContext, ActionDescriptor actionDescriptor) {
        return BuildUp(base.GetControllerAttributes(controllerContext, actionDescriptor));
    }

    protected override IEnumerable<FilterAttribute> GetActionAttributes(ControllerContext controllerContext, ActionDescriptor actionDescriptor) {
        return BuildUp(base.GetActionAttributes(controllerContext, actionDescriptor));
    }

    private IEnumerable<FilterAttribute> BuildUp(IEnumerable<FilterAttribute> attributes) {
        foreach (var attr in attributes)
            container.BuildUp(attr);
        return attributes;
    }
}
10
задан Bill the Lizard 18 May 2011 в 15:36
поделиться