0

I am practicing using the Service / Repository pattern in a C# / .NET 8 app and have some questions about best practices.

Below is an example interface for one of the services:

namespace NCAAMB.Services.Interfaces;

public interface IEspnBasketballService
{
    Task<EspnBasketballTeam?> GetBasketballTeam();

    string GetTeamName(EspnBasketballTeam? team);

    string GetNextEventId(EspnBasketballTeam? team);
}

And the corresponding service class:

namespace NCAAMB.Services;

public class EspnBasketballService : IEspnBasketballService
{
    private readonly ILogger<EspnBasketballService> _logger;
    private readonly IEspnBasketballRepository _espnRepo;

    public EspnBasketballService(GetBasketballTeam() espnRepo, ILogger<EspnBasketballService> logger)
    {
        _espnRepo = espnRepo;
        _logger = logger;
    }

    public Task<EspnBasketballTeam?> GetBasketballTeam() => _espnRepo.GetBasketballTeam();

    public string GetTeamName(EspnBasketballTeam? team)
    {
        try
        {
            if (team == null)
            {
                throw new Exception("Team obj was null.");
            }

            return team?.team?.name ?? string.Empty;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex.Message);
        }

        return string.Empty;
    }

    public string GetNextEventId(EspnBasketballTeam? team)
    {
        try
        {
            if (team == null)
            {
                throw new Exception("Team obj was null.");
            }

            return team?.team?.nextEvent?.First()?.id ?? string.Empty;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex.Message);
        }

        return string.Empty;
    }
}

What I think I got right:

  • I believe GetBasketballTeam() is being used in the service correctly which is calling IEspnBasketballRepository to fetch data from an API endpoint

What I think I currently got wrong:

  • I am thinking GetTeamName() and GetNextEventId() should not be included in the service. If not, what do you think is best practice for housing these methods? Utility class, extension methods, etc? I would also like the ability to have these methods testable and include logging.

Any suggestions and examples? Thanks in advance!

4
  • 1
    May I ask why you are using the Repository (anti-)Pattern? What actual problems are you trying to solve with it? Commented Aug 23, 2024 at 7:58
  • 1
    Your GetTeamName method needs serious re-thinking... Commented Aug 23, 2024 at 7:59
  • 1
    You're using try/catch and throw incorrectly... In C#/.NET, Exceptions are exceptional - they are not for control-flow - and try + throw + catch is just wrong. Commented Aug 23, 2024 at 8:00
  • 1
    Why on earth does a team have a team property that has a name property? If a Team has-a Team, why is it a Team? That's beyond confusing. If your EspnBasketballTeam just had a Name, you wouldn't need a method to get it in the first place. Commented Aug 23, 2024 at 8:13

1 Answer 1

1

If you have just "passthorugh" method as GetBasketballTeam that passes result directly from calling other method (on other service), I wonder why not just inject to calling class repo itself and call the method?

Pro - we don't need another wrapper service and can use repo method directly - less code.

Con - we need to inject another class. If you must inject IEspnBasketballService and it makes sense to define such method for getting the team there, you can define it there to not inject yet another dependency there.

It's all matter of opinion.

Going further, for getting next event and team's name - they don't depend on anything, but i can see little logic (exception handling, null handling), so it's worth extracting this to separate method. But for that we can use static methods or even extension methods.

Pros of having static/extension method - less code (no need to define interface, implementation, etc.).

Cons - degraded unit testability - while you are perfectly able to test static methods, code using them will be harder to test (depending on how complex logic lies in static method).

So, again matter of opinion - what's cleaner for you, what are your expectations in terms of unit testability, etc.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.