Вопрос

Я пытаюсь внедрить модель с сеансом на запрос в своем приложении WCF, и я прочитал бесчисленные документы по этой теме, но, похоже, нет полной демонстрации этого. Я на самом деле наткнулся на некоторые очень полезные статьи, подобные этой:

Изессия Nhibernate, подключенная к одному WCF-вызову

Но все это со старых времен, когда у Nhibernate и Ninject не было конкретных реализаций WCF, поэтому они достигли того, что мне нужно, внедрив своих поставщиков пользовательских услуг и т. Д. Поскольку и Ninject, и Nhibernate теперь имеют поддержку WCF, я хочу сохранить вещи. Используя их модули, но я оказался здесь ...

Основная настройка и поток должны быть чем -то вроде этого:

  1. Установить CurrentSessionContext для wcfoperationsessionContext в конфигурации nhibernate
  2. При запуске службы, начало запроса или в любом месте времени инициирования, открывайте сеанс и свяжите его с текущим контекстом
  3. Репозитории Получить текущий экземпляр сеанса с использованием метода sessionFactory.getCurrentSession ()
  4. Раскрыть и закрыть сеанс в конце жизненного цикла

Моя первоначальная проблема заключалась в том, что я не смог получить доступ к жизненному циклу WCF, чтобы справиться с моими привязками. После того, как я немного выкопался в код Ninject, мне удалось подключить свои методы к событиям открытия / закрытия ServiceHost без большого изменения, но тогда я не смог получить доступ к OperationContext, поскольку он статичен потоком.

Позже я попытался обеспечить совместимость ASP.NET и использование Application_beginRequest и Application_endrequest, и это выглядело очень многообещающе, но я не думаю, что это лучшее решение, поскольку я должен быть обязательным веществом с экземпляром службы, а не для HTTP -запроса.

Кто-нибудь когда-нибудь достиг этого, используя встроенные библиотеки расширения WCF от Ninject? Или какие -либо идеи о том, что я мог бы сделать не так?

Это было полезно?

Решение

Я реализовал с помощью сессии запроса с помощью IdispatchmessageinspectorАнкет Вероятно, вы можете реализовать пользовательский менеджер по жизни для Ninject для достижения веб -запроса.

Другие советы

Герметичный

Вы можете сделать следующее:

public class DomainModule : NinjectModule
{
    private const string RealSessionIndicator = "RealSession";

    private readonly ProxyGenerator proxyGenerator = new ProxyGenerator();

    public override void Load()
    {
        this.Bind<ISession>().ToMethod(ctx => ctx.Kernel.Get<ISessionFactory>().OpenSession())
            .When(r => r.Parameters.Any(p => p.Name == RealSessionIndicator))
            .InRequestScope();

        this.Bind<Func<ISession>>().ToMethod(ctx => () => ctx.Kernel.Get<ISession>(new Parameter(RealSessionIndicator, (object)null, true)));

        this.Bind<ISession>()
            .ToMethod(this.CreateSessionProxy)
            .InTransientScope();

        this.Bind<ISessionFactory>().ToMethod(ctx => ctx.Kernel.Get<Configuration>().BuildSessionFactory()).InSingletonScope();
    }

    private ISession CreateSessionProxy(IContext ctx)
    {
        var session = (ISession)this.proxyGenerator.CreateInterfaceProxyWithoutTarget(typeof(ISession), new[] { typeof(ISessionImplementor) }, ctx.Kernel.Get<SessionInterceptor>());
        return session;
    }
}

public class SessionInterceptor : IInterceptor
{
    private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

    private readonly Func<ISession> sessionProvider;

    public SessionInterceptor(Func<ISession> sessionProvider)
    {
        this.sessionProvider = sessionProvider;
    }

    public void Intercept(IInvocation invocation)
    {
        try
        {
            var session = this.sessionProvider();
            invocation.ReturnValue = invocation.Method.Invoke(session, invocation.Arguments);
        }
        catch (TargetInvocationException exception)
        {
            Log.Error(exception);
            throw;
        }
    }
}

При этом вы можете использовать везде Isession, не заботясь о деталях. Вы можете редактировать InrequestScope с помощью inscope (ctx => raycontext.current), чтобы использовать область WCF

Вы можете сделать это, используя точки расширения, представленные в IinstanceContextProvider Интерфейс.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top