想把一个已有接口 IZzkDocService
public interface IZzkDocService
{
Task<SearchResult> SearchAsync(string appName, ZzkQuery query);
bool UpdateDocuments(string appName, params int[] ids);
}
拆分为3个接口
public interface ISearchService
{
Task<SearchResult> SearchAsync(string appName, ZzkQuery query);
}
public interface IIndexService
{
bool UpdateDocuments(string appName, params int[] ids);
}
public interface IZzkDocService : ISearchService, IIndexService
{
}
请问拆分后原先实现 IZzkDocService
接口的 ZzkDocService
如何针对这3个接口向依赖注入容器注册?
找到了只需注册一次的最简单解决方法(方法3),注入 IZzkDocService 直接赋值给 ISearchService 与 IIndexService
public class Program
{
private static async Task Main(string[] args)
{
IServiceCollection services = new ServiceCollection();
services.AddTransient<IZzkDocService, ZzkDocService>();
IServiceProvider sp = services.BuildServiceProvider();
ISearchService searchService = sp.GetRequiredService<IZzkDocService>();
IIndexService indexService = sp.GetRequiredService<IZzkDocService>();
await searchService.SearchAsync("blog", new ZzkQuery() { Words = "C#" });
indexService.UpdateDocuments("blog", 1);
}
}
public interface ISearchService
{
Task<SearchResult> SearchAsync(string appName, ZzkQuery query);
}
public interface IIndexService
{
bool UpdateDocuments(string appName, params int[] ids);
}
public interface IZzkDocService : ISearchService, IIndexService
{ }
public class ZzkDocService : IZzkDocService
{
public Task<SearchResult> SearchAsync(string appName, ZzkQuery query)
{
Console.WriteLine(nameof(SearchAsync));
return Task.FromResult(new SearchResult());
}
public bool UpdateDocuments(string appName, params int[] ids)
{
Console.WriteLine(nameof(UpdateDocuments));
return true;
}
}
ISearchService searchService = sp.GetRequiredService<IZzkDocService>();
这么做的实际意义在什么地方😂
@czd890: 当前 IZzkDocService
堆积了很多方法,通过引入 ISearchService
与 IIndexService
进行拆分,旧代码暂时不改,依然使用 IZzkDocService
,新写或者重构的代码使用新接口
@dudu: 新的代码里面就不好.GetRequiredService<IZzkDocService>了呀, 应该要直接 .GetRequiredService<ISearchService> ?? 不晓得是不是理解错了...
@czd890: 新代码里可以这样
public class BlogPostReviewEventHandler
{
private readonly IIndexService _indexService;
public BlogPostReviewEventHandler(IZzkDocService zzkDocService)
{
_indexService = zzkDocService;
}
}
@dudu: 和继承一样,如果 IZzkDocService 是 IIndexService 的子类,也可以这样直接赋值
@dudu: 新代码不是和旧代码没有任何区别了么?? 新的BlogPostReviewEventHandler不是应该只依赖于IIndexService 么, 它不再需要知晓 IZzkDocService 了. 不是么.
@czd890: IZzkDocService
只是在构造函数注入时用一下,BlogPostReviewEventHandler 的实现只依赖 IIndexService
,与 ILogger
有些类似
public class BlogPostReviewEventHandler
{
private readonly ILogger _logger;
public BlogPostReviewEventHandler(ILogger<BlogPostReviewEventHandler> logger)
{
_logger = logger;
}
}
这个意思吗?
services.add<ISearchService,...>
services.add<IIndexService,...>
services.add<IZzkDocService ,ZzkDocService>
class ZzkDocService : IZzkDocService
{
ctor(ISearchService, IIndexService )
}
实现就只有一个 ZzkDocService
@dudu:
services.add<IZzkDocService ,ZzkDocService>
services.add<ISearchService>(sp=>sp.getservice<IZzkDocService>())
services.add<IIndexService>(sp=>sp.getservice<IZzkDocService>())
services.add<ZzkDocService>
services.add<IZzkDocService >(sp=>sp.getservice<ZzkDocService>())
services.add<ISearchService>(sp=>sp.getservice<ZzkDocService>())
services.add<IIndexService>(sp=>sp.getservice<ZzkDocService>())
internal class ZzkDocService{}
如果是 autofac 可以用 AsImplementedInterfaces 把当前class注册到所有他实现了的interface
@czd890: 这是方法1与方法2,我采用了方法3