2

I found a few articles outlining the reason why the DependencyResolver in C# MVC should be avoided

But I also found a pattern of injecting a "base dependency" into a constructor, and that class essentially hold all instances the app's dependencies, but obviously not in a sigleton, each time the dependencies are instantiated anew

// example possibly to be avoided
public interface IBaseDependencies
{
    IClientRepo ClientRepo { get; }
    IProductRepo ProductRepo { get; }
    /// more here
}

..but while I love the simplicity of passing dependencies in this way, the problem is ALL the depencies will be instantiated but they may not all be required, so to avoid that performce hit, I thought to add C#'s Lazy<> class like so...

// Is this example any better?
public interface ILazyBaseDependencies
{
    #region IClientRepo

    private readonly Lazy<IClientRepo> ClientRepoLazy =
        new Lazy<IClientRepo>(() => DependencyResolver.Current.GetService<IClientRepo>());

    public IClientRepo ClientRepo => ClientRepoLazy.Value;

    #endregion  

    /// more here
}

So now the dependency is only instantiated when it is called directly. The larger the project, the more the "base dependencies" approach becomes useful, but will it hurt performance to do this this way?

nobody.price
  • 221
  • 1
  • 14
Ninjanoel
  • 2,864
  • 4
  • 33
  • 53
  • Many of the service containers have support for factory registration in lots of forms, like taking a dependency on `Func` for instance, which allows you to defer the actual construction of a service until needed. **However**, if your services are costly to construct, you may be designing them incorrectly. But yes, using a service locator that you pass around is indeed an antipattern. – Lasse V. Karlsen Jan 02 '20 at 12:03
  • And your question is loaded. "Will it hurt performance?" It depends on what kind of performance you're talking about. It may not hurt runtime performance of your app, but in the long term, sprinkling calls to a service locator throughout your code will hurt *development* performance. It will be harder to set up tests and maintain the dependencies. – Lasse V. Karlsen Jan 02 '20 at 12:05
  • It is also important that when you ask "will this incur a performance hit?" you have a clear notion of "... compared to ...". All code requires cpu time to execute, the question is whether you have any better alternatives to compare to. – Lasse V. Karlsen Jan 02 '20 at 12:07
  • Thank for the comments @LasseV.Karlsen. Regarding performance, I'm asking if I compare constructor injection against using dependencyResolver – Ninjanoel Jan 02 '20 at 13:35
  • Again, if your services are costly to construct, you may be designing them incorrectly. It should not be a problem injecting the services directly into your constructor, even if you are conditionally going to use them or not. The problem is that there's no right answer here. It depends. – Lasse V. Karlsen Jan 02 '20 at 14:23
  • It's not about how costly the service is, they'll cost what they cost, but I would not want to add extra overhead while loading a service just to have a slightly more comfortable life as a coder – Ninjanoel Jan 02 '20 at 16:33

1 Answers1

1

I wouldn't call that a pattern, but rather a code smell. At the very least, it violates the Interface Segregation Principle as well as the Dependency Inversion Principle.

Will it hurt performance? Only you can answer that question.

Mark Seemann
  • 225,310
  • 48
  • 427
  • 736
  • Ok, so my scenario is that in my 'API' library (where all my logic sits) everything is constructor injected as it should be, but code that uses that library, the web front end in this instance, I think my 'lazy base dependencies' pattern is a decent compromise because the code that needs to SOLID is so, and in MVC webfront my constructors are much tidier. I just not seen this pattern described or discussed anywhere and I really like it so I'm trying to research what people think. – Ninjanoel Jan 02 '20 at 13:31
  • Regarding performance, I'm only asking if it's known whether DependencyResolver is slower than constructor injection. From my experience, this pattern is alot more maintainable than constructor injection in this instance, so regarding that article, I'd say I should use this pattern and not worry about performance, but on the scale of some projects, when I'm being asked to shave milliseconds off page load times, is this pattern known to be slower? – Ninjanoel Jan 02 '20 at 13:45
  • from the article about perfomance: "(Caveat: writing performance benchmarks that provide high-quality, meaningful results can be somewhat tricky in a garbage-collected, JIT-compiled runtime. I see this done wrong a lot. I will return to this topic in a future blog post.)" -- which is basically the whole reason I'm asking and not trying to write a performance test myself – Ninjanoel Jan 02 '20 at 13:48