我的Startup.cs
包含40个存储库:
services.AddScoped<IUserRepository, UserRepository>();
services.AddScoped<IXRepository, XRepository>();
... 40 more lines ...
我试图找到一种方法将这个混乱局限在一条线上,但是我惨遭失败地想到这一点,我有几种方法在界面中没有。有人能提供一些帮助吗?我明白为什么它不起作用,它没有一个具体的存储库,但我没有接近使这项工作。
InvalidOperationException: Unable to resolve service for type...
// IRepository.cs
public interface IRepository
{
}
// IUserRepository.cs
public interface IUserRepository : IRepository
{
User ReadToken(string email, string password);
}
// BaseRepository.cs
public class BaseRepository : IDisposable
{
protected IDbConnection PostgreSQL;
public BaseRepository(IDbConnection postgreSQL)
{
PostgreSQL = postgreSQL;
}
public void Dispose()
{
}
}
// UserRepository.cs
public class UserRepository : BaseRepository, IUserRepository
{
public UserRepository(IDbConnection postgreSQL) : base(postgreSQL)
{
}
public User ReadToken(string email, string password)
{
object parameters;
string sql;
parameters = new
{
email,
password
};
sql =
@"
SELECT
user_id AS id,
token
FROM users
WHERE
email = @email AND
password = CRYPT(@password, password) AND
active = TRUE;
";
var user = base.PostgreSQL.Query<User>(sql, parameters).SingleOrDefault();
if (user == null)
throw new UnauthorizedException("User", "User not found.");
return user;
}
}
// UsersController.cs
public class UsersController : ControllerBase
{
protected IUserRepository UserRepository;
public UsersController(IUserRepository userRepository)
{
UserRepository = userRepository;
}
}
// Startup.cs
services.AddTransient<IRepository, BaseRepository>();
答案 0 :(得分:3)
您要找的是convention based registration
。这使您能够注册所有类型,例如以Repository
结尾作为它们实现的接口。但是,内置的ASP.NET Core IOC非常轻量级,并且不提供此类功能。因此,您可以使用扫描所有引用程序集的代码将其包装起来,按模式查找类型,然后将它们添加到ServiceCollection,或者您可以使用提供此功能的不同IOC实现并支持.Net Core,例如Autofac,StructureMap等。
答案 1 :(得分:2)
您可以使用Scrutor
执行此操作它为Microsoft.Extensions.DependencyInjection提供程序集扫描和装饰扩展
所有这些存储库可以总结为这样的东西:
services.Scan(x => x.FromAssemblyOf<IAnAssemblyRegistrationMarker>()
.AddClasses(filter => filter.AssignableTo(typeof(IRepository)))
.AsImplementedInterfaces()
.WithScopedLifetime());
IAnAssemblyRegistrationMarker
是一个空接口,指向要扫描的程序集(项目)
AddClasses
从所选程序集中添加所有符合
AsImplementedInterfaces
将每个匹配的具体类型注册为其所有已实现的接口
WithScopedLifetime
使用Scoped Lifetime注册每个匹配的具体类型(您还有WithSingletonLifetime
和WithTransientLifetime
)
上面代码示例中的唯一要求是存储库实现IRepository
,以便您只定位必要的项目。
免责声明:我与Scrutor无任何关联。我喜欢这件事。