为了账号安全,请及时绑定邮箱和手机立即绑定

Autofac:如何在 SingleInstance 范围内使用每个请求依赖项?

Autofac:如何在 SingleInstance 范围内使用每个请求依赖项?

C#
ibeautiful 2021-10-23 16:58:10
有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;        }    }}正在创建此命令 ApplicationOAuthProviderpublic 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        });    }}permissions = await mediator.Send(new GetRolePermissions.Command { UserRoles = user.Roles });-GetRolePermissions.Handler需要注入时抛出错误IDbConnection,但当前的 autofac 范围ApplicationOAuthProvider是"root"并且没有iDbConnection在此范围内注册。但它存在于per-request范围内。不想perLifettime用于 IDbConnection,因为我认为,dbConnection在不必要时应该关闭它。我想这样做:using(var scope = AutofacConfig.container.BeginLifiTime("AutofacWebRequest")) {      permissions = await mediator.Send(new GetRolePermissions.Command { UserRoles = user.Roles });}但无法使此解决方案起作用。而且我不知道如何正确获取容器,现在它是我手动设置的 AutofacConfig 的静态变量。如何启用的注入IDbConnection到这个GetPermissions.Handler?
查看完整描述

1 回答

?
慕婉清6462132

TA贡献1804条经验 获得超2个赞

实际上,InstancePerLifetimeScope()就是您要寻找的解决方案。您需要做的就是注入 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

        }

    }

}

它确实改变了作为请求作用域的子作用域的行为,但我不确定这是否是您的代码的问题 - 试一试,它应该可以正常工作。如果没有,那么你知道去哪里问。;)


查看完整回答
反对 回复 2021-10-23
  • 1 回答
  • 0 关注
  • 129 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信