C# 从Windsor迁移到Simple Injector时,HttpContext.Current.Session为空
我目前正试图从温莎城堡迁移到简易注射器 在服务中,我是否尝试注入HttpSessionStateBase,如以下服务构造函数所示:C# 从Windsor迁移到Simple Injector时,HttpContext.Current.Session为空,c#,asp.net-mvc,dependency-injection,simple-injector,C#,Asp.net Mvc,Dependency Injection,Simple Injector,我目前正试图从温莎城堡迁移到简易注射器 在服务中,我是否尝试注入HttpSessionStateBase,如以下服务构造函数所示: public UserSession(IResourceRepository resourceRepository, IUser user, IRoleResolver roleResolver, IApproverRepository approverRepository, IActiveDirectory activeDirectory, Ht
public UserSession(IResourceRepository resourceRepository, IUser user,
IRoleResolver roleResolver, IApproverRepository approverRepository,
IActiveDirectory activeDirectory, HttpSessionStateBase httpSession,
Settings appSettings)
{
_resourceRepository = resourceRepository;
_user = user;
_roleResolver = roleResolver;
_approverRepository = approverRepository;
_activeDirectory = activeDirectory;
_httpSession = httpSession;
_allowedUsernamePostfixes = appSettings.AuthenticationAllowedUsernamePostfixes;
}
要使用Windsor实现这一点,我可以使用FactoryMethod将HttpSessionStateBase作为新的HttpSessionStateWrapper注入
private static IWindsorContainer BuildWindsorContainer()
{
var container = new WindsorContainer();
container.Kernel.Resolver.AddSubResolver(
new CollectionResolver(container.Kernel, true));
container.Register(
Component.For<IWindsorContainer>().Instance(container)
);
container.Install(FromAssembly.This());
container.Register(
Component.For<HttpRequestBase>()
.UsingFactoryMethod(() => new HttpRequestWrapper(HttpContext.Current.Request))
.LifestyleTransient(),
Component.For<HttpSessionStateBase>()
.UsingFactoryMethod(() => new HttpSessionStateWrapper(HttpContext.Current.Session))
.LifestyleTransient(),
return container;
}
私有静态IWindsorContainer BuildWindsorContainer()
{
var container=新的WindsorContainer();
container.Kernel.Resolver.AddSubResolver(
新的CollectionResolver(container.Kernel,true));
集装箱。登记(
Component.For().Instance(容器)
);
container.Install(fromsassembly.This());
集装箱。登记(
用于()的组件
.UsingFactoryMethod(()=>新的HttpRequestWrapper(HttpContext.Current.Request))
.生活方式,
用于()的组件
.UsingFactoryMethod(()=>新的HttpSessionStateWrapper(HttpContext.Current.Session))
.生活方式,
返回容器;
}
在Global.asax.cs文件内的ASP.NET MVC 4项目的应用程序启动方法中调用此方法时,此方法将起作用
我现在尝试将其转换为Simple Inject,方法是将两个Windsor FactoryMethods放置在下面的Simple Inject代码中:
container.Register<HttpRequestBase>(
() => new HttpRequestWrapper(HttpContext.Current.Request),
Lifestyle.Transient);
container.Register<HttpSessionStateBase>(
() => new HttpSessionStateWrapper(HttpContext.Current.Session),
Lifestyle.Transient);
container.Register(
()=>新的HttpRequestWrapper(HttpContext.Current.Request),
生活方式(短暂的);
集装箱。登记(
()=>新的HttpSessionStateWrapper(HttpContext.Current.Session),
生活方式(短暂的);
问题是,当我在Application_Start方法中调用此方法时,当Simple Inject调用container verify方法时,HttpContext.Current.Session将为null
有人能解决这个问题吗
问题是,当我在Application_Start方法中调用此方法时,当Simple Inject调用container verify方法时,HttpContext.Current.Session将为null
对于Castle Windsor,如果它像Simple Injector一样包含验证功能,您也会遇到同样的问题。如果您删除对container.Verify()
的调用,您将获得与Castle Winsdor相同的行为,即您不会获得任何验证
显然,这并不理想,这可能是您希望迁移到简单注入器的原因之一
您遇到的问题归结为使用运行时状态构造应用程序组件的问题,运行时状态是一种代码气味。因此,在理想情况下,您应该缓解这一问题,并确保HttpContext.Current
不称为suring object construction,而仅在对象构造之后
尽管您确实应该努力做到这一点,但我可以理解,重构应用程序可能是一项相当艰巨的任务,这比仅仅更改DI容器要花费更多的时间。不过,在不久的将来,您应该记住这一点
也就是说,一个实用的(暂时的)解决方法是在初始化期间创建假的HttpRequest
和HttpSession
对象,如下所示:
container.Register<HttpRequestBase>(
() => HttpContext.Current != null
? new HttpRequestWrapper(HttpContext.Current.Request)
: new HttpRequestWrapper(new HttpRequest("", "http://fake", "")),
Lifestyle.Scoped);
container.Register<HttpSessionStateBase>(
() => HttpContext.Current != null
? new HttpSessionStateWrapper(HttpContext.Current.Session)
: (HttpSessionState)typeof(HttpSessionState)
.GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic)
.First()
.Invoke(new object[] { null }),
Lifestyle.Scoped);
container.Register(
()=>HttpContext.Current!=null
?新的HttpRequestWrapper(HttpContext.Current.Request)
:新建HttpRequestWrapper(新建HttpRequest(“,”http://fake", "")),
生活方式(范围);
集装箱。登记(
()=>HttpContext.Current!=null
?新的HttpSessionStateWrapper(HttpContext.Current.Session)
:(HttpSessionState)类型(HttpSessionState)
.GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic)
.First()
.Invoke(新对象[]{null}),
生活方式(范围);
这相当难看,尤其是创建
HttpSessionState
(具有内部构造函数),但它使您的其余配置保持可验证性。您好,您是正确的,代码使用运行时数据时会有异味。遗憾的是,基于应用程序的创建者使用运行时数据围绕服务进行身份验证…我尝试了您的一些代码,但无法使HttpSessionStateBase正常工作,因为没有隐式在HttpSessionStateWrapper和HttpSessionState之间键入。很抱歉,我没有时间测试代码。希望这能为您提供一些解决此问题的建议。