C# Dotnet 核心

编程入门 行业动态 更新时间:2024-10-21 11:57:51
本文介绍了C# Dotnet 核心 - 在构造函数中实现泛型 DBContext 的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在为从长期停工中恢复过来而苦苦挣扎.

I am struggling with this coming back from a long layoff.

我问了一个问题在我的通用基础存储库中配置 DBContext.只有在用户登录后,我才能构造连接字符串,因此我无法在 startup.cs 中注册服务 - 我必须使用构造函数参数来实例化我的 DBContext.

I asked a question regarding the configuring of a DBContext in my generic base repository. Only after a user has logged in can I then construct a connection string so I cannot register a service in startup.cs - I have to use a constructor argument to instantiate my DBContext.

我得到了这个答案,我认为这可以解决问题,但是我在以下工厂类中遇到错误:

I got this answer which I thought would address the problem however I am getting an error in the following factory class:

public class ContextFactory<T> : IContextFactory<T> : where T : DbContext { public T CreateDbContext(string connectionString) { var optionsBuilder = new DbContextOptionsBuilder<T>(); optionsBuilder.UseSqlServer(connectionString); return new T(optionsBuilder.Options); } }

错误在行上 return new T(optionsBuilder.Options); 是:

The error is on the line return new T(optionsBuilder.Options); and is:

无法创建变量类型 'T' 的实例,因为它没有有 new() 约束

Cannot create an instance of the variable type 'T' because it does not have the new() constraint

推荐答案

即使添加了new()约束,最终也会出现如下错误

Even if you add new() constraint, you will end up with the following error

'T':创建变量类型的实例时不能提供参数.

'T': cannot provide arguments when creating an instance of a variable type.

您获得的代码无效.

新约束指定泛型类声明中的任何类型参数都必须具有公共无参数构造函数.要使用新约束,类型不能是抽象的.

The new constraint specifies that any type argument in a generic class declaration must have a public parameterless constructor. To use the new constraint, the type cannot be abstract.

参考 新约束(C# 参考)

另一个需要考虑的选项是使用 Activator.CreateInstance (Type, Object[]).

Another option to consider could be to use Activator.CreateInstance (Type, Object[]).

给定

public interface IContextFactory<TContext> where TContext : DbContext { TContext Create(string connectionString); }

您将按如下方式实现它

public class ContextFactory<TContext> : IContextFactory<TContext> where TContext : DbContext { public TContext Create(string connectionString) { var optionsBuilder = new DbContextOptionsBuilder<TContext>(); optionsBuilder.UseSqlServer(connectionString); return (TContext)Activator.CreateInstance(typeof(TContext), optionsBuilder.Options); } }

这可以进一步重构以分离关注点

This could be refactored further to separate concerns

public class ContextFactory<TContext> : IContextFactory<TContext> where TContext : DbContext { public TContext Create(DbContextOptions<TContext> options) { return (TContext)Activator.CreateInstance(typeof(TContext), options); } }

这样建造者将成为工厂使用地点的责任.

so that the builder will become the responsibility of where the factory is being used.

var connection = @"...."; var optionsBuilder = new DbContextOptionsBuilder<BloggingContext>(); optionsBuilder.UseSqlServer(connection); //Assuming factory is `IContextFactory<BloggingContext>` using (var context = factory.Create(optionsBuilder.Options)) { // do stuff }

编辑

工厂可以在ConfigureServices方法中注册为开放泛型

The factory can be registered as open generics in ConfigureServices method

services.AddSingleton(typeof(IContextFactory<>), typeof(ContextFactory<>));

更多推荐

C# Dotnet 核心

本文发布于:2023-11-16 18:34:13,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1606781.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:核心   Dotnet

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!