简体   繁体   English

另一个服务中1个功能的依赖注入

[英]Dependency Injection for 1 function in another service

Bit new to dependency injection, but so far i like it. 依赖注入有点新,但到目前为止我喜欢它。 Setting up all my services with interfaces so i can mock the services for unit testing, all good. 用接口设置我的所有服务,以便我可以模拟用于单元测试的服务,一切都很好。

I have come to a part where i have a function in 1 service that i need to access from another service. 我来到了其中我需要从另一项服务访问的一项服务中的功能。 Is it ok to inject the whole service just to access that one function? 可以仅通过访问一项功能就注入整个服务吗?

I have a delete function (mark as delete) in my module service, and i need to also delete all the related pages to that module. 我的模块服务中有一个删除功能(标记为删除),我还需要删除该模块的所有相关页面。 Since a user can also delete a Page, i have put all the page code in the PageService and anything for a module in the ModuleService. 由于用户也可以删除页面,因此我将所有页面代码都放在了PageService中,并将所有模块代码都放在了ModuleService中。 This was it is in one place and i dont have to retype the code in each service. 这是在一个地方,我不必在每个服务中都重新输入代码。 I have this on more than just these 2 service in my real code. 在我的实际代码中,我不仅在这两个服务上拥有此功能。

So here is my example 所以这是我的例子

public interface IModuleService
{
    Task<int> DeleteAsync(Module entity);

    Task<int> DeleteAsync(Module entity, bool saveChanges);
}

public interface IPageService
{
    Task<int> DeleteAsync(Page entity);

    Task<int> DeleteAsync(Page entity, bool saveChanges);
}

public ModuleService : IModuleService
{
    public Task<int> DeleteAsync(Module entity)
    {
        return DeleteAsync(entity, true);
    }

    public async Task<int> DeleteAsync(Module entity, bool saveChanges)
    {
        foreach (var page in entity.Pages)
            await _pageService.DeleteAsync(page);

        entity.IsDeleted = true;

        if (saveChanges)
            return await _context.SaveChangesAsync();
        else
            return await Task.FromResult<int>(1);
    }

    private IDbContext _context;
    private IPageService _pageService;

    public ModuleService(IDbContext context, IPageService pageService)
    {
        _context = context;
        _pageService = pageService;
    }
}

public PageService : IPageService
{
    public Task<int> DeleteAsync(Page entity)
    {
        return DeleteAsync(entity, true);
    }

    public async Task<int> DeleteAsync(Page entity, bool saveChanges)
    {
        // you can see that i have injected yet another service into this
        foreach (var item in entity.Children)
            await _itemService.DeleteAsync(item);

        entity.IsDeleted = true;

        if (saveChanges)
            return await _context.SaveChangesAsync();
        else
            return await Task.FromResult<int>(1);
    }

    private IDbContext _context;
    private IItemService _itemService;

    public PageService(IDbContext context, IItemService itemService)
    {
        _context = context;
        _itemService = itemService;
    }
}

Now a user can delete a module by calling 现在,用户可以通过调用来删除模块

_moduleService.DeleteAsync(myModule);

and it will also delete all related pages, and each pages related items and calls SaveChangesAsync once, so its all in 1 transaction. 并且还会删除所有相关页面,并且每个页面相关的项目并调用一次SaveChangesAsync,因此其所有事务都是1次的。

A user can also delete a page by calling 用户也可以通过调用来删除页面

_pageService.DeleteAsync(myPage);

and it will also delete all related items and again calls SaveChangesAsync once. 并且还会删除所有相关项,然后再次调用SaveChangesAsync。

It this the right way to go about it with Dependency Injection? 这是依赖注入实现的正确方法吗? Inject the whole service so i can access 1 method? 注入整个服务,以便我可以访问1种方法?

As for me it's ok in your case to inject the whole(but little) service just for one function. 对于我来说,可以为一个功能注入整个(但很少)服务。 But i would suggest you to set cascade delete = true if it is possible. 但我建议您设置级联delete = true(如果可能)。 In this case you can remove a lot of your code and perhaps you will not need dependency injection in this example at all. 在这种情况下,您可以删除许多代码,也许在此示例中根本不需要依赖注入。

Update If you store your modules and pages in database you can set CascadeDelete = true option for module->page foreign key. 更新如果将模块和页面存储在数据库中,则可以为模块->页面外键设置CascadeDelete = true选项。 In this case database will automatically remove all pages if you delete appropriate module. 在这种情况下,如果删除适当的模块,数据库将自动删除所有页面。 The same for page and it's children. 页面和子项相同。 At least you will be able to remove this piece of code foreach (var page in entity.Pages) await _pageService.DeleteAsync(page); 至少您将能够foreach (var page in entity.Pages) await _pageService.DeleteAsync(page);中为foreach (var page in entity.Pages) await _pageService.DeleteAsync(page);删除这段代码foreach (var page in entity.Pages) await _pageService.DeleteAsync(page); and this foreach (var item in entity.Children) await _itemService.DeleteAsync(item); 这个foreach (var item in entity.Children) await _itemService.DeleteAsync(item);
As a result you will not need any more _pageService and _itemService variables and as result no need of dependency injection at all 结果,您将不再需要_pageService_itemService变量,因此根本不需要依赖项注入

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM