Ответ 1
Я выполнил за всю жизнь сеанса запроса с помощью IDispatchMessageInspector. Вероятно, вы могли бы реализовать пользовательский менеджер времени жизни для Ninject для достижения каждого веб-запроса.
Я пытаюсь реализовать модель сеанса за запрос в моем приложении WCF, и я прочитал бесчисленные документы по этой теме, но похоже, что это не полная демонстрация этого. Я натолкнулся на некоторые очень полезные статьи, такие как этот:
NHibernate ISession, ограниченный одним WCF-вызовом
но все они из старых дней, когда NHibernate и Ninject не имели конкретных реализаций WCF, поэтому они достигли того, что мне нужно, внедряя своих заказных поставщиков услуг и т.д. Так как у Ninject и NHibernate есть поддержка WCF сейчас, я хочу держите вещи в согласии, используя их модули, но я оказался здесь...
Базовая установка и поток должны быть примерно такими:
Моя первоначальная проблема заключалась в том, что я не смог получить доступ к жизненному циклу wcf для обработки привязок. После некоторого копания в код ninject мне удалось подключить мои методы к событиям открытия/закрытия ServiceHost без значительных изменений, но тогда я не смог получить доступ к OperationContext, поскольку он является поточно-статическим.
Позже я попытался включить совместимость asp.net и использовать Application_BeginRequest и Application_EndRequest, и это выглядело очень многообещающим, но я не думаю, что лучшее решение, поскольку я должен привязывать материал к экземпляру службы, а не HTTP-запрос.
Кто-нибудь когда-либо достигал этого, используя встроенные библиотеки расширения wcf ninject? Или любые идеи о том, что я могу делать неправильно?
Я выполнил за всю жизнь сеанса запроса с помощью IDispatchMessageInspector. Вероятно, вы могли бы реализовать пользовательский менеджер времени жизни для Ninject для достижения каждого веб-запроса.
Hy
Вы можете сделать следующее:
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 = > OperationContext.Current) для использования области WCF
Возможно, вы сможете это сделать, используя точки расширения, указанные в интерфейсе IInstanceContextProvider.