2
\$\begingroup\$

I've got a service that loads data from a databasr and it performs almost the same operations in all methods.

   private async Task GetProvenances()
    {
        try
        {
            var result = await commonRepository.GetProvenances();
            if (result != null)
            {
                provenanceContainerService.Provenances = result;
                LogTo.Information(InitCacheMessages.STR_GET_PROVENANCES, result.Count);
            }
            else
            {
                LogTo.Warning(InitCacheMessages.STR_GET_PROVENANCES_FAILED);
            }
        }
        catch (Exception ex)
        {
            exceptionService.HandleException(ex);
        }
    }

    private async Task GetPkInstrumentMarkets()
    {
        try
        {
            var result = await commonRepository.GetPkInstrumentMarkets();
            if (result != null)
            {
                pkInstrumentMarketContainerService.PkInstrumentMarkets = result;
                LogTo.Information(InitCacheMessages.STR_GET_PK_INSTRUMENT_MARKETS, result.Count);
            }
            else
            {
                LogTo.Warning(InitCacheMessages.STR_GET_PK_INSTRUMENT_MARKETS_FAILED);
            }
        }
        catch (Exception ex)
        {
            exceptionService.HandleException(ex);
        }
    }

    private async Task GetPkMotivations()
    {
        try
        {
            var result = await commonRepository.GetPkMotivations();
            if (result != null)
            {
                pkMotivationsContainerService.PkMotivations = result;
                LogTo.Information(InitCacheMessages.STR_GET_PK_MOTIVATIONS, result.Count);
            }
            else
            {
                LogTo.Warning(InitCacheMessages.STR_GET_PK_MOTIVATIONS_FAILED);
            }
        }
        catch (Exception ex)
        {
            exceptionService.HandleException(ex);
        }
    }

How can I refactor this so I don't have to repeat the same code for about 30 methods?

UPDATE 1

Hello, I've done this way this night

  protected async Task PerformInitInternal(string okMessage, string koMessage, Func<Task<IList<T>>> function)
    {
        try
        {
            var result = await function();
            if (result != null)
            {
                Items = result;
                LogTo.Information(okMessage, result.Count);
            }
            else
            {
                LogTo.Warning(koMessage);
            }

            isInitialized = true;

        }
        catch (Exception ex)
        {
            ExceptionService.HandleException(ex);
        }
    }

And I call it this way

  public override Task Init()
    {
        return PerformInitInternal(InitCacheMessages.STR_GET_COUNTERPARTS,
            InitCacheMessages.STR_GET_COUNTERPARTS_FAILED, () => CommonRepository.GetCrossSplitAsync());
    }

Can this be ok?

\$\endgroup\$
7
  • \$\begingroup\$ Use a delegate. \$\endgroup\$
    – RubberDuck
    Commented Feb 3, 2016 at 13:08
  • \$\begingroup\$ can you please provide me a sample? since it's async \$\endgroup\$
    – advapi
    Commented Feb 3, 2016 at 13:22
  • 1
    \$\begingroup\$ @advapi - delegates can be async too. E.g. async lamdba: async (commonRepository) => await commonRepository.GetProvenances()) \$\endgroup\$
    – RobH
    Commented Feb 3, 2016 at 14:46
  • \$\begingroup\$ I'm not able to solve this problem...feel really dumb, can you please post me how the method should like? \$\endgroup\$
    – advapi
    Commented Feb 3, 2016 at 15:39
  • \$\begingroup\$ Please edit your post to add additional context code, we need to know what a commonRepository is, for example. Mind including the fields and constructor of that class? \$\endgroup\$ Commented Feb 3, 2016 at 16:49

1 Answer 1

2
\$\begingroup\$

It's hard to review just a small part of your code like this (for example, the way you're using Items and isInitialized looks like code smell to me, but it's hard to tell like this), so I'll focus on what I can actually see.


protected async Task PerformInitInternal(string okMessage, string koMessage, Func<Task<IList<T>>> function)
  • It's an asynchronous method, so its name should end with Async. Also, PerformInit is pretty vague, maybe a more concrete name could be better, for example, LoadData?
  • While the symmetry between OK and KO is fun, I don't think koMessage is a good name. successMessage and errorMessage would be better.
  • Speaking of which, do you actually need both messages? Or any messages at all? I would consider a completely generic message, assuming the rest of the message can be inferred from other parts of the log, like the type name.
  • function is too vague.
\$\endgroup\$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.