如何将通用存储库(或业务逻辑层)注入 ViewModel
Posted
技术标签:
【中文标题】如何将通用存储库(或业务逻辑层)注入 ViewModel【英文标题】:How to Inject Generic Repository(Or Business Logic Layer) Into ViewModel 【发布时间】:2021-01-17 19:37:09 【问题描述】:为简单起见,我想将通用存储库注入到视图模型中。我将 ViewModel 和 Repository 添加到服务集合中,ViewModel 依赖于 Repository。根据我的阅读,应该自动解析 ViewModel 的构造函数参数,因为它使用的是 IConfiguration。我已经尝试在 Services
中显式实例化 ViewModel,但仍然出现相同的运行时错误,并且在创建存储库的另一个实例时似乎无法达到目的。
Repository/IRepository 看起来像这样
public class Repository<TPoco, TDatabaseConnection> : IRepository<TPoco, TDatabaseConnection>
where TPoco : class
where TDatabaseConnection : IDbConnection, new()
public Repository(IConfiguration configuration, string connectionName = "DefaultConnection" )//SqlConnectionConfiguration configuration) //(string connectionString)
_connectionString = configuration.GetConnectionString(connectionName);
_configuration = configuration;
...
查看模型
public class PersonViewModel
private IRepository<Person, IDbConnection> _PersonRepository;
public List<Person> Persons get; set;
public PersonViewModel(IRepository<Person, IDbConnection> personRepository)
_PersonRepository=personRepository;
...
在 Startup.cs 文件中,我添加如下服务:
services.AddScoped<IRepository<Person, SQLiteConnection>, Repository<Person, SQLiteConnection>>();
services.AddScoped<PersonViewModel>(); //runtime errors here
我收到两个运行时错误 (System.AggregateException
)
Inner Exception 1:
InvalidOperationException: Error while validating the service descriptor 'ServiceType: BlazorInjection.ViewModels.PersonViewModel Lifetime: Scoped ImplementationType: BlazorInjection.ViewModels.PersonViewModel': Unable to resolve service for type 'DapperRepository.IRepository`2[BlazorInjection.Models.Person,System.Data.IDbConnection]' while attempting to activate 'BlazorInjection.ViewModels.PersonViewModel'.
Inner Exception 2:
InvalidOperationException: Unable to resolve service for type 'DapperRepository.IRepository`2[BlazorInjection.Models.Person,System.Data.IDbConnection]' while attempting to activate 'BlazorInjection.ViewModels.PersonViewModel'.
我错过了一个概念吗?我该如何纠正这个问题?
【问题讨论】:
这可能对stevejgordon.co.uk/…有帮助 【参考方案1】:将类结构更改为:
public class PersonViewModel
private IRepository<Person> _PersonRepository;
public List<Person> Persons get; set;
public PersonViewModel(IRepository<Person> personRepository)
_PersonRepository = personRepository;
public interface IDbConnection
public class Person
public interface IRepository<TPoco>
public class SQLiteConnection : IDbConnection
private string _connectionString;
private IConfiguration _configuration;
public SQLiteConnection(IConfiguration configuration, string connectionStringName)
_connectionString = configuration.GetConnectionString(connectionStringName);
_configuration = configuration;
public class Repository<TPoco> : IRepository<TPoco>
where TPoco : class
public IDbConnection Connection get;
public Repository(IDbConnection connection)
Connection = connection;
与Startup.cs
相比,只需更改为
services.AddScoped<IDbConnection>(sp => ActivatorUtilities.CreateInstance<SQLiteConnection>(sp, "defaultConnectionStringName"));
services.AddScoped(typeof(IRepository<>), typeof(Repository<>));
services.AddScoped<PersonViewModel>();
注意通用存储库注册,它可以轻松扩展您的数据层。 ActivatorUtilities
允许您将当前范围 container
服务与自定义参数结合起来。从设计的角度来看,我认为这种方式(一个通用的注入连接)也更好,因为您的存储库客户端不需要知道底层数据库实现。
【讨论】:
我试过了。我收到关于隐式转换的错误:There is no implicit reference conversion from 'DapperRepository.Repository<BlazorInjection.Models.Person, System.Data.SQLite.SQLiteConnection>' to 'DapperRepository.IRepository<BlazorInjection.Models.Person, System.Data.IDbConnection>'.
Does System.Data.SQLiteConnection not implement IDbConnection?
也试过了。类似的错误。它要求参数,所以我这样做了。 services.AddScoped<IRepository<Person, IDbConnection>>(sp => new Repository<Person, SQLiteConnection>(Configuration));
我收到两个错误:CS1662 Cannot convert lambda expression to intended delegate type because some of the return types in the block are not implicitly convertible to the delegate return type
和第二个要求明确 cast.hmm ?
有什么理由需要存储库是双重通用的吗?如果没有,您可以将 IDbConnection 作为构造函数参数
我让我的存储库实例化 dbconnection。我想没有必要。我可以尝试将其作为参数传入
请查看修改后的答案以上是关于如何将通用存储库(或业务逻辑层)注入 ViewModel的主要内容,如果未能解决你的问题,请参考以下文章