简体   繁体   中英

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. 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.

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.

It this the right way to go about it with Dependency Injection? Inject the whole service so i can access 1 method?

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. 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. 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); and this 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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