依賴注入
官網(wǎng)介紹
https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-2.2
Scrutor
- 開源地址https://github.com/khellang/Scrutor
- 參考文檔 https://www.cnblogs.com/catcher1994/p/10316928.html
手動(dòng)管理依賴注入過于麻煩,當(dāng)有多個(gè)倉(cāng)儲(chǔ),服務(wù),無(wú)法統(tǒng)一注入,Scrutor能幫助我們簡(jiǎn)化ASP.NET Core的DI注冊(cè)。
在ConfigServices中,我們?cè)拘枰@樣子依次注入倉(cāng)儲(chǔ),服務(wù)和其他接口及實(shí)現(xiàn),當(dāng)有多個(gè)倉(cāng)儲(chǔ)時(shí),這樣就過于繁瑣。
services.AddTransient<IUserRepository, UserRepository>();
services.AddTransient<IUserService, UserService>();
services.AddTransient<ICurrentUser, CurrentUser>();
Serivce后綴服務(wù)注入DI
當(dāng)我們有多個(gè)Service后綴的服務(wù)時(shí),使用以下方法,可將服務(wù)掃描只留下以Serivce結(jié)尾的類,將其類型注冊(cè)為提供所有公共接口生成服務(wù),其生命周期為Transient,
services.Scan(scan => scan
//加載Startup這個(gè)類所在的程序集
.FromAssemblyOf<Startup>()
// 表示要注冊(cè)那些類,上面的代碼還做了過濾,只留下了以 Service 結(jié)尾的類
.AddClasses(classes => classes.Where(t => t.Name.EndsWith("Service", StringComparison.OrdinalIgnoreCase)))
//表示將類型注冊(cè)為提供其所有公共接口作為服務(wù)
.AsImplementedInterfaces()
//表示注冊(cè)的生命周期為 Transient
.WithTransientLifetime()
);
ITransientDependency
新建一個(gè)空接口,當(dāng)其他類繼承此接口后,統(tǒng)一注入到DI中,以Transient的生命周期。
namespace LinCms.Zero.Dependency
{
public interface ITransientDependency
{
}
}
接口
public interface ICurrentUser
{
int? Id { get; }
int? GroupId { get; }
bool? IsAdmin { get; }
}
模擬實(shí)現(xiàn)
public class CurrentUser : ICurrentUser, ITransientDependency
{
public int? Id => 1;
public int? GroupId => 2;
public bool? IsAdmin => true;
}
掃描所有繼承ITransientDependency的實(shí)現(xiàn)。
services.Scan(scan => scan
// We start out with all types in the assembly of ITransientService
.FromAssemblyOf<ITransientDependency>()
// AddClasses starts out with all public, non-abstract types in this assembly.
// These types are then filtered by the delegate passed to the method.
// In this case, we filter out only the classes that are assignable to ITransientService.
.AddClasses(classes => classes.AssignableTo<ITransientDependency>())
// We then specify what type we want to register these classes as.
// In this case, we want to register the types as all of its implemented interfaces.
// So if a type implements 3 interfaces; A, B, C, we'd end up with three separate registrations.
.AsImplementedInterfaces()
// And lastly, we specify the lifetime of these registrations.
.WithTransientLifetime()
);
如何使用
在其他類中使用此接口
[ApiController]
[Route("cms/user")]
public class UserController : ControllerBase
{
private readonly ICurrentUser _currentUser;
public UserController(ICurrentUser currentUser)
{
_currentUser = currentUser;
}
[HttpGet]
public int GetUser()
{
return _currentUser.Id;
}
}
統(tǒng)一注入
當(dāng)然,我們可以統(tǒng)一注入,而非寫二次servics.Scan
services.Scan(scan => scan
.FromAssemblyOf<Startup>()
.AddClasses(classes => classes.Where(t => t.Name.EndsWith("Service",StringComparison.OrdinalIgnoreCase)))
.AsImplementedInterfaces()
.WithTransientLifetime()
.FromAssemblyOf<ITransientDependency>()
.AddClasses(classes => classes.AssignableTo<ITransientDependency>())
.AsImplementedInterfaces()
.WithTransientLifetime()
);