好吧,我刚才的问题/设置有太多的变数,所以我剥离下来到它的裸露的骨头组成。
下面给出使用StructureMap3代码...
//IoC setup
For<HttpContextBase>().UseSpecial(x => x.ConstructedBy(y => HttpContext.Current != null ? new HttpContextWrapper(HttpContext.Current) : null ));
For<ICurrentUser>().Use<CurrentUser>();
//Classes used
public class CurrentUser : ICurrentUser
{
public CurrentUser(HttpContextBase httpContext)
{
if (httpContext == null) return;
if (httpContext.User == null) return;
var user = httpContext.User;
if (!user.Identity.IsAuthenticated) return;
UserId = httpContext.User.GetIdentityId().GetValueOrDefault();
UserName = httpContext.User.Identity.Name;
}
public Guid UserId { get; set; }
public string UserName { get; set; }
}
public static class ClaimsExtensionMethods
public static Guid? GetIdentityId(this IPrincipal principal)
{
//Account for possible nulls
var claimsPrincipal = principal as ClaimsPrincipal;
if (claimsPrincipal == null)
return null;
var claimsIdentity = claimsPrincipal.Identity as ClaimsIdentity;
if (claimsIdentity == null)
return null;
var claim = claimsIdentity.FindFirst(x => x.Type == ClaimTypes.NameIdentifier);
if (claim == null)
return null;
//Account for possible invalid value since claim values are strings
Guid? id = null;
try
{
id = Guid.Parse(claim.Value);
}
catch (ArgumentNullException) { }
catch (FormatException) { }
return id;
}
}
这怎么可能在监视窗口?
我有我升级到使用StructureMap 3.X从2.x的Web应用程序,但我发现在特定依赖古怪的行为。
我有一个ISecurityService,我用它来获得核实一些事情,当用户请求一个页面。 该服务依赖一个小界面,我已经叫ICurrentUser上。 类的实现是非常简单的,实际上它可能是一个结构。
public interface ICurrentUser
{
Guid UserId { get; }
string UserName { get; }
}
这是通过使用下面的代码依赖注入获得。
For<ICurrentUser>().Use(ctx => getCurrentUser(ctx.GetInstance<HttpContextBase>()));
For<HttpContextBase>().Use(() => getHttpContext());
private HttpContextBase getHttpContext()
{
return new HttpContextWrapper(HttpContext.Current);
}
private ICurrentUser getCurrentUser(HttpContextBase httpContext)
{
if (httpContext == null) return null;
if (httpContext.User == null) return null; // <---
var user = httpContext.User;
if (!user.Identity.IsAuthenticated) return null;
var personId = user.GetIdentityId().GetValueOrDefault();
return new CurrentUser(personId, ClaimsPrincipal.Current.Identity.Name);
}
当一个请求到来时,我的网站广泛认证首先发生,这取决于ISecurityService
。 出现这种情况OWIN内,似乎之前发生HttpContext.User
已被填充,所以它的空,就这样吧。
后来,我有检查一个ActionFilter,通过ISecurityService
,如果当前用户已经同意当前版本的TermsOfUse为网站,如果他们不被重定向到该页面首先同意给他们。
这一切都在structuremap 2.x中工作得很好 对于我的迁移StructureMap3我已经安装了NuGet包StructureMap.MVC5帮助速度东西了我。
当我的代码获取到线在我ActionFilter检查使用的术语我有这个。
var securityService = DependencyResolver.Current.GetService<ISecurityService>();
agreed = securityService.CheckLoginAgreedToTermsOfUse();
里面的CheckLoginAgreedToTermsOfUse()
我的情况下CurrentUser
为空。 尽管它会hazve成功了,我getCurrentUser的内部断点()似乎从来没有被击中。 它几乎一样,如果它是一个定局,因为它是空的最后一次,即使它已经解决了这个时候。
我有种莫名其妙,为什么getCurrentUser()
不会被调用上请求ISecurityService
。 我甚至尝试明确坚持一个.LifecycleIs<UniquePerRequestLifecycle>()
我联播处理ICurrentUser
没有效果。
更新:好了,所以刚一抬头,我用下面接受的方法开始,虽然它一直很大,到目前为止,它并没有解决我的核心问题。 原来,新StructureMap.MVC5
,基于StructureMap3
,使用NestedContainers。 其范围及其对NestedContainer的寿命,而不管默认的是瞬态的请求。 所以,当我要求HttpContextBase
首次,它就会返回同一个实例的请求(即使后来在要求的寿命,已经时过境迁的其余部分。你需要或者不使用NestedContainer(其中,因为我了解它的东西ASP.NET vNext)复杂化,或明确设置的生命周期For<>().Use<>()
映射给你每次请求一个新的实例。需要注意的是每NestedContainer此作用域会导致控制器问题以及在MVC。虽然StructureMap.MVC5
包处理这与ControllerConvention
,它不处理意见,并使用递归的景色或多次可能会导致你的问题很好,我还在寻找的一个永久性的修复查看问题,目前我已经收归DefaultContainer
。