首页 新闻 会员 周边 捐助

C#: 接口继承的依赖注入问题

0
悬赏园豆:50 [已解决问题] 解决于 2023-02-09 15:19

想把一个已有接口 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个接口向依赖注入容器注册?

dudu的主页 dudu | 高人七级 | 园豆:30755
提问于:2023-02-09 10:34
< >
分享
最佳答案
0

找到了只需注册一次的最简单解决方法(方法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;
    }
}
dudu | 高人七级 |园豆:30755 | 2023-02-09 15:16
ISearchService searchService = sp.GetRequiredService<IZzkDocService>();

这么做的实际意义在什么地方😂

czd890 | 园豆:14488 (专家六级) | 2023-02-09 17:18

@czd890: 当前 IZzkDocService 堆积了很多方法,通过引入 ISearchServiceIIndexService 进行拆分,旧代码暂时不改,依然使用 IZzkDocService,新写或者重构的代码使用新接口

dudu | 园豆:30755 (高人七级) | 2023-02-09 17:39

@dudu: 新的代码里面就不好.GetRequiredService<IZzkDocService>了呀, 应该要直接 .GetRequiredService<ISearchService> ?? 不晓得是不是理解错了...

czd890 | 园豆:14488 (专家六级) | 2023-02-14 17:22

@czd890: 新代码里可以这样

public class BlogPostReviewEventHandler
{
    private readonly IIndexService _indexService;

    public BlogPostReviewEventHandler(IZzkDocService zzkDocService)
    {
        _indexService = zzkDocService;
    }
}
dudu | 园豆:30755 (高人七级) | 2023-02-14 17:26

@dudu: 和继承一样,如果 IZzkDocService 是 IIndexService 的子类,也可以这样直接赋值

dudu | 园豆:30755 (高人七级) | 2023-02-14 17:28

@dudu: 新代码不是和旧代码没有任何区别了么?? 新的BlogPostReviewEventHandler不是应该只依赖于IIndexService 么, 它不再需要知晓 IZzkDocService 了. 不是么.

czd890 | 园豆:14488 (专家六级) | 2023-02-14 18:22

@czd890: IZzkDocService 只是在构造函数注入时用一下,BlogPostReviewEventHandler 的实现只依赖 IIndexService,与 ILogger 有些类似

public class BlogPostReviewEventHandler
{
    private readonly ILogger _logger;

    public BlogPostReviewEventHandler(ILogger<BlogPostReviewEventHandler> logger)
    {
        _logger = logger;
    }
}
dudu | 园豆:30755 (高人七级) | 2023-02-14 18:28
其他回答(1)
0

这个意思吗?

services.add<ISearchService,...>
services.add<IIndexService,...>
services.add<IZzkDocService ,ZzkDocService>

class ZzkDocService : IZzkDocService
{
    ctor(ISearchService, IIndexService )
}
收获园豆:50
czd890 | 园豆:14488 (专家六级) | 2023-02-09 10:48

实现就只有一个 ZzkDocService

支持(0) 反对(0) dudu | 园豆:30755 (高人七级) | 2023-02-09 11:17

@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

支持(0) 反对(0) czd890 | 园豆:14488 (专家六级) | 2023-02-09 12:38

@czd890: 这是方法1与方法2,我采用了方法3

支持(0) 反对(0) dudu | 园豆:30755 (高人七级) | 2023-02-09 15:17
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册