There are IDbConnection
connection dependency registered as per-request
and ApplicationOAuthProvider
registered as single instance
.
builder.Register(c => new SqlConnection(WebConfigUtils.DefaultConnectionString))
.As<IDbConnection>()
.InstancePerRequest();
builder.RegisterType<ApplicationOAuthProvider>()
.As<IOAuthAuthorizationServerProvider>()
.PropertiesAutowired()
.SingleInstance();
Need to store user permissions in the identity claims. For this purpose I have created command GetRolePermissions, and in this command I want to inject IDbConnection
instance.
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;
}
}
}
This command is being created in the 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 });
- throws an error as GetRolePermissions.Handler
need to inject IDbConnection
, but current autofac scope of ApplicationOAuthProvider
is "root"
and there is no iDbConnection
registered in this scope. But it exists in the per-request
scope.
Don't want to use perLifettime
for IDbConnection, because I think, that dbConnection
should be closed when it is unneccessary. I was think to do smth like this:
using(var scope = AutofacConfig.container.BeginLifiTime("AutofacWebRequest"))
{
permissions = await mediator.Send(new GetRolePermissions.Command { UserRoles = user.Roles });
}
but can't make this solution working. And I don't know how to get the container properly, for now it static variable of AutofacConfig, that I set manually.
How to enable injection of IDbConnection
into this GetPermissions.Handler
?
Actually, InstancePerLifetimeScope()
is the solution that you look for. All you need to do is to inject DbConnection factory that produces owned ( docs link 1 and docs link 2 ) instances of DbConnection rather then DbConnection itself.
// 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
}
}
}
It does change behavior for the scopes that are children of request scope, but I'm not sure if it's a problem for your code or not - just give it a try, chances are that it should work fine. If not then you know where to ask. ;)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.