有IDbConnection
个连接依赖项已注册为per-request
和ApplicationOAuthProvider
已注册为single instance
。
builder.Register(c => new SqlConnection(WebConfigUtils.DefaultConnectionString))
.As<IDbConnection>()
.InstancePerRequest();
builder.RegisterType<ApplicationOAuthProvider>()
.As<IOAuthAuthorizationServerProvider>()
.PropertiesAutowired()
.SingleInstance();
需要在身份声明中存储用户权限。为此,我创建了命令GetRolePermissions,并在此命令中注入IDbConnection
实例。
public class GetRolePermissions
{
public class Command: IRequest<List<string>>
{
public ICollection<AspNetUserRole> UserRoles { get; set; }
}
public class Handler : AsyncRequestHandler<Command, List<string>>
{
private IDbConnection databaseConnection;
public Handler(IDbConnection databaseConnection)
{
this.databaseConnection = databaseConnection;
}
}
}
此命令正在ApplicationOAuthProvider
public class ApplicationOAuthProvider : OAuthAuthorizationServerProvider
{
private async Task<ClaimsIdentity> GenerateUserIdentityAsync(AspNetUser user, string authenticationType)
{
user.SecurityStamp = Guid.NewGuid().ToString();
var identity = await mediator.Send(new GenerateUserIdentity.Command
{
AuthenticationType = authenticationType,
User = user
});
List<string> permissions = null;
permissions = await mediator.Send(new GetRolePermissions.Command { UserRoles = user.Roles });
var permissionClaimValue = permissions != null && permissions.Count > 0
? permissions.Aggregate((resultString, permission) => resultString + "," + permission)
: "";
identity.AddClaim(new Claim(AuthenticationConstants.Gender, user.Gender.ToString()));
identity.AddClaim(new Claim(AuthenticationConstants.Permissions, permissionClaimValue));
return identity;
}
}
permissions = await mediator.Send(new GetRolePermissions.Command { UserRoles = user.Roles });
-抛出错误,因为GetRolePermissions.Handler
需要注入IDbConnection
,但是当前ApplicationOAuthProvider
的autofac范围是"root"
,并且没有{{1 }}在此范围内注册。但是它存在于iDbConnection
范围内。
不想为IDbConnection使用per-request
,因为我认为,perLifettime
不必要时应关闭。我以为是这样的:
dbConnection
但是不能使该解决方案起作用。而且我不知道如何正确获取容器,因为它是我手动设置的AutofacConfig静态变量。
如何启用将using(var scope = AutofacConfig.container.BeginLifiTime("AutofacWebRequest"))
{
permissions = await mediator.Send(new GetRolePermissions.Command { UserRoles = user.Roles });
}
注入此IDbConnection
?
答案 0 :(得分:1)
实际上,InstancePerLifetimeScope()
是您要寻找的解决方案。您所需要做的就是注入DbConnection 工厂,该DbConnection产生DbConnection的拥有的(docs link 1和docs link 2)实例,而不是DbConnection本身。
// registration
builder.RegisterType<SqlConnection>()
.As<IDbConnection>()
.WithParameter(new NamedParameter("connectionString", WebConfigUtils.DefaultConnectionString))
.InstancePerLifetimeScope();
// usage
public class GetRolePermissions
{
public class Command: IRequest<List<string>>
{
public ICollection<AspNetUserRole> UserRoles { get; set; }
}
public class Handler : AsyncRequestHandler<Command, List<string>>
{
private Func<Owned<IDbConnection>> _connectionFactory;
public Handler(Func<Owned<IDbConnection>> connectionFactory)
{
_connectionFactory = connectionFactory;
}
// not really sure where your consuming code is, so just something off the top of my head
public DontKnowYourResultType Handle(GetRolePermissions.Command cmd) {
using (var ownedConnection = _connectionFactory()) {
// ownedConnection.Value is the DbConnection you want
// ... do your stuff with that connection
} // and connection gets destroyed upon leaving "using" scope
}
}
}
它确实改变了属于请求范围的子范围的行为,但是我不确定这对您的代码是否有问题-请尝试一下,可能它应该可以正常工作。如果没有,那么你知道在哪里问。 ;)