Simple Injector, dependency injection of services and multiple instances - asp.net-mvc

I am using Simple Injector for my DI library. I have controllers in my asp.net MVC site that take services in their constructors via this library. When I look at the Diagnostic Tools in Visual Studio and see my Managed Memory I see multiple instances of the same service.
var container = new Container();
container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();
container.RegisterWebApiControllers(GlobalConfiguration.Configuration);
container.RegisterMvcControllers(Assembly.GetExecutingAssembly());
container.RegisterMvcIntegratedFilterProvider();
RegisterComponents(container);
container.Verify();
DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
My question is, is this by design. I figured one IPaymentsService would be used throughout all the controllers but I have a count of 187? I would think it should be 1.
I am thinking about adding the below line. Seems to be working fine, and now I see 700,000 KB less of memory used and a 10+ second faster load time on the site. Is there any downside with this?
container.Options.DefaultLifestyle = Lifestyle.Scoped;

Let me start with the basics, most of which you will likely be familiar with, but let’s do it for completeness and correctness.
With Simple Injector, Transient means short-lived and not cached. If service X is registered as Transient, and multiple components depend on X, each get their own new instance. Even if X implements IDisposable, it is not tracked nor disposed of. After creation, Simple Injector forgets about Transients immediately.
Within a specifically defined scope (e.g. a web request), Simple Injector will only create a single instance of a service registered as Scoped. If service X is Scoped, and multiple components depend on X, all components that are created within that same scope get the same instance of X. Scoped instances are tracked and if they implement IDisposable (or IAsyncDisposable), Simple Injector calls their Dispose method when the scope is disposed of. In the context of a web request disposal of scopes (and therefore Scoped components) this managed for you by the Simple Injector integration packages.
With Singleton, Simple injector will ensure at most one instance of that service within a single Container instances. If you have multiple Container instances (which you typically wouldn’t in production, but more likely during testing) each Container instance gets its own cache with Singletons.
The described behavior is specific to Simple Injector. Other DI Containers might have different behavior and definitions when it comes to these lifestyles:
Simple Injector considers a Transient component short lived, possibly including state, while the ASP.NET Core DI (MS.DI) considers Transient components to be *stateless, living for any possible duration. * Because of this different view, with MS.DI, Transients can be injected into Singletons, while with Simple Injector you can’t. Simple Injector will give an diagnostic error when you call Verify().
Transients are not disposed of by Simple Injector. That’s why you get a diagnostic error when you register a Transient that implements IDisposable. Again, this is very different with some other DI Containers. With MS.DI, transients are tracked and disposed of when their scope, from which they are resolved, is disposed of. There are pros and cons to this. Important con is that this will lead to accidental memory leaks when resolving disposable transients from the root container, because MS.DI will store those Transients forever.
About choosing the right lifestyle for a component:
Choosing the correct lifestyle (Transient/Scoped/Singleton) for a component is a delegate matter.
If a component contains state that should be reused throughout the whole application, you might want to register that component as Singleton -or- move the state out of the component and hide it behind a service which component can be registered as Singleton.
The expected lifetime of a component should never exceed that of its consumers. Transient is the shortest lifestyle, while Singleton is the longest. This means that a Singleton component should only depend on other Singletons, while Transient components can depend on both Transient, Scoped, and Singleton components. Scoped components should typically only have Scoped and Singleton dependencies.
The previous rule, however, is quite strict, which is why with Simple Injector v5 we decided to allow Scoped components take a dependency on Transient components as well. This will typically be fine in case scopes live for a short period of time (as is with web requests in web applications). If, however, you have long-running operations that operate within a single scope, but do regularly call back into the container to resolve new instances, having Scoped instances depend on (stateful) Transients could certainly cause trouble; that’s, however, not a very common use case.
Failing to adhere to the rule of “components should only depend on equal or longer-lived components,” results in Captive Dependencies. Simple Injector calls them “Lifestyle Mismatches,” but it’s the same thing.
A stateless component with no dependencies can be registered as Singleton.
The lifestyle of a stateless component with dependencies, depends on the lifestyle of its dependencies. If it has components that are either Scoped or Transient, it should itself be either Scoped or Transient. If it were registered as Singleton, that would lead to its dependencies becoming Captive Dependencies.
If a stateless component only has Singleton dependencies, it can be registered as Singleton as well.
When it comes to selecting the correct lifestyles for your components in the application, there are two basic Composition Models to choose from, namely the Ambient Composition Model and the Closure Composition Model. I wrote a series of five blog posts on this starting here. With the Ambient Composition Model you’ll make all components in your application stateless and store state outside of the object graphs. This allows you to register almost all your components as Singleton, but it does lead to complications and likely a somewhat different design of your application.
It's, therefore, more likely that you are applying the second Composition Model: The Closure Composition Model. This is the most common model, and used by most developers and pushed by most application frameworks (e.g. ASP.NET Core DI). With the Closure Composition Model, you would typically register most of your components as Transient. Only the few components in your application that do contain state would be registered as either Scoped or Singleton. Although you could certainly “tune” composition by looking at the consumers and dependencies of components and decide to increase the lifestyle (to Scoped or even Singleton) to prevent unneeded creation of instances, downside of this is that is more fragile.
For instance, if you have a stateless component X that depends on a Singleton component Y, you can make component X a Singleton as well. But once Y requires a Scoped or Transient dependency of its own, you will not only have to adjust the lifestyle of Y, but of X as well. This could cascade up the dependency chain. So instead, with the Closure Composition Model, it would typically be normal to keep things “transient unless.”
About performance:
Simple Injector is highly optimized, and it would typically not make much difference if a few extra components are created. Especially if they are stateless. When running a 32 bits process, such class would consume “8 + (4 * number-of-dependencies)” bytes of memory. In other words, a stateless component with 1 dependency consumes 12 bytes of memory, while a component with 5 dependencies consumes 28 bytes (assuming a 32 bits processes; multiply this by 2 under 64 bits).
On the other hand, managing and composing Scoped instances comes with its own overhead. Although Simple Injector is highly tuned in this regard, Scoped instances need to be cached and resolved from the scope’s internal dictionary. This comes at a cost. This means that creating a component with no dependencies a few times as Transient in a graph is likely faster than having it resolved as Scoped.
Under normal conditions, you wouldn’t have to worry about the amount of extra memory and the amount of extra CPU it takes to produce those extra Transient instances. But perhaps you are not under normal conditions. The following abnormal conditions could cause trouble:
If you violate the simple-injection-constructors rule: When a component’s constructor does more than simply storing its supplied dependencies (for instance calling them, doing I/O or something CPU intensive or memory intensive) creating extra transient instances can hurt a lot. You should absolutely try to stay away from this situation whenever possible.
**Your application creates massive object graphs: ** If object graphs are really big, you’ll likely see certain components being depended upon multiple (or even many) times in the graph. If the graph is massive (thousands of individual instances), this could lead to the creation of hundreds or even thousands of extra objects, especially when those components have Transient dependencies of their own. This situation often happens when components have many dependencies. If for instance your application’s components regularly have more than 5 dependencies, you’ll quickly see the size of the object graph explode. Important to note here is that this is typically caused by a violation of the Single Responsibility Principle. Components get many dependencies when they are doing too much, taking too many responsibilities. This easily causes them to have many dependencies, and when their dependencies have many dependencies, things can explode quite easily. The real solution in that case is to make your components smaller. For instance, if you have classes like “OrderService” and “CustomerService”, they will likely have a hodgepodge of functionality and a big list of dependencies. This causes a myriad of problems; big object graphs being one of them. Fixing this in an existing application, however, is typically not easy; it requires a different design and a different mindset.
In these kinds of scenarios changing a component’s lifestyle can be beneficial for the performance of the application. You already seem to have established this in your application. In general, changing the lifestyle from Transient to Scoped is a pretty safe change. This is why Simple Injector v5 doesn’t complain anymore when you inject Transient dependencies into Scoped consumers.
This will not be the case, however, when you have a stateful Transient component, while each consumer does expect to get its own state; in that case, changing it to Scope would in fact break your application. However, this is not a design that I typically endorse. Although I’ve seen this type of composition a few times in the past, I never do this in my applications; IMO it leads to unneeded complexity.
TLDR;
Long story short, there are a lot of factors to consider, and perhaps a lot of places in the application where the design could be approved, but in general (especially in the context of web requests) changing the lifestyle of stateless components from Transient to Scoped is usually pretty safe. If this results in a big performance win in your application, you can certainly consider making Scoped the default lifestyle.

Related

Dagger #Reusable scope vs #Singleton

From the User's Guide:
Sometimes you want to limit the number of times an #Inject-constructed
class is instantiated or a #Provides method is called, but you don’t
need to guarantee that the exact same instance is used during the
lifetime of any particular component or subcomponent.
Why would I use that instead of #Singleton?
Use #Singleton if you rely on singleton behavior and guarantees. Use #Reusable if an object would only be a #Singleton for performance reasons.
#Reusable bindings have much more in common with unscoped bindings than #Singleton bindings: You're telling Dagger that you'd be fine creating a brand-new object, but if there's a convenient object already created then Dagger may use that one. In contrast, #Singleton objects guarantee that you will always receive the same instance, which can be much more expensive to enforce.
In general, Dagger and DI prefer unscoped objects: Creating a new object is a great way to keep state tightly-contained, and allows for objects to be garbage-collected as soon as the dependent object can. Dagger shows some of this preference built-in: In Dagger unscoped objects can be mixed in to any component or module, regardless of whether the component is scope-annotated. This type of unscoped binding is also useful for stateless objects like injectable (mockable) utility classes and implementations of strategy, command, and other polymorphic behavioral design patterns: The objects should be bound globally and injected for testing/overrides, but instances don't keep any state and short-lived or disposable.
However, in Android and other performance- and memory-constrained environments, it goes against performance recommendations to create a lot of temporary objects (as described on android.com but removed since January 2022), because instance creation and garbage collection are both more-expensive processes than on desktop VMs. This leads to the pragmatic solution of marking an object #Singleton, not because it's important to always get the same instance, but just to conserve instances. This works, but is semantically-weak, and also has memory and speed implications: Your short-lived util or strategy pattern object now has to exist as long as your application exists, and must be accessed through double-checked locking, or else you risk violating the "one instance only" #Singleton guarantee that is unnecessary here. This can be a source of increased memory usage and synchronization overhead.
The compromise is in #Reusable bindings, which have instance-conserving properties like #Singleton but are excepted from the scope-matching #Component rule just like unscoped bindings—which gives you more flexibility about where you install them. (See tests.) They have a lifespan only as long as the outermost component that uses them directly, and will opportunistically use an instance from an ancestor to conserve further, but without double-checked locking to save on creation costs. (Consequently, several instances of a #Reusable object may exist simultaneously in your object graph, particularly if they were requested on multiple threads at the same time.) Finally, and most importantly, they're a signal to you and future developers about the way the class is intended to be used.
Though the cost is lower, it's not zero: As Ron Shapiro notes on Medium, "Reusable has many of the same costs as Singleton. It saves synchronization, but it still forces extra classes to be loaded at app startup. The real suggestion here is to never scope unless you’ve profiled and you’ve seen a performance improvement by scoping." You'll have to evaluate the speed and memory effects yourself: #Reusable is another useful tool in the toolbox, but that doesn't mean it's always or obviously a good choice.
In short, #Singleton would work, but #Reusable has some distinct performance advantages if the whole point is performance instead of object lifecycle. Don't forget to measure performance before and after you mark an instance #Reusable, to make sure #Reusable is really a benefit for your use case.
Follow-up question from saiedmomen: "Just to be 100% clear things like okhttpclient, retrofit and gson should be declared #Reusable. right??"
Yes, in general I think it'd be good to declare stateless utilities and libraries as #Reusable. However, if they secretly keep some state—like handling connection limits or batching across all consumers—you might want to make them #Singleton, and if they are used very infrequently from a long-lived component it might still make sense to make them scopeless so they can be garbage-collected. It's really hard to make a general statement here that works for all cases and libraries: You'll have to decide based on library functionality, memory weight, instantiation cost, and expected lifespan of the objects involved.
OkHttpClient in particular does manage its own connection and thread pools per instance, as Wyko points out in the comments, and Albert Vila Calvo likewise notes Retrofit's intended-singleton behavior. That would make those good candidates for #Singleton over #Reusable. Thanks Wyko and Albert!

ASP.NET MVC ModelBinders.Binders thread-safety

I would like to confirm some questions about ModelBinderDictionary in asp.net mvc:
A single instance of ModelBinderDictionary is stored in ModelBinders.Binders static property. So during the whole application lifetime, we will have only one instance of ModelBinderDictionary.
But I found that ModelBinderDictionary is not thread-safe. What if two threads add model binders to ModelBinders.Binders at the same time (not in the Application_Start, but in some controller)?
I guess the reason why ModelBinderDictionary is not designed to be thread-safe is that ModelBinders.Binders is supposed to be accessed only in application start, so thread-safety is not needed because there'll be only one thread running in Application_Start, correct?
So if we are designing a class supposed to be accessed at any time, we have to make it thread-safe. Otherwise we don't need to guarantee thread-safty and simply do it like ModelBinderDictionary, correct?
So this is also about Trade-Off. Although adding model binders to ModelBinders.Binders at any time is allowed, but no one will do that. So we don't need to design for such rare case. That's why we don't guarantee thread-safety for ModelBinderDictionary, correct?

Factory classes vs closures in Zend Framework 2

Is it better to use factory classes or closures in Zend Framework 2, and why?
I know that closures cannot be serialized, but if you return them from Module#getServiceConfig(), this will not affect the caching of the rest of your configuration data, and the closures would be cached in your opcode cache anyway.
How does performance differ in constructing a factory class vs executing a closure? Does PHP wrap and instantiate closures only when you execute them, or would it do this for every closure defined in your configuration file on every request?
Has anyone compared the execution times of each method?
See also:
Dependency management in Zend Framework 2 MVC applications
Passing forms vs raw input to service layer
PHP will convert the anonymous functions in your configuration to instances of the closure class at compile time so it would do this on every request. This is unlike create_function which will create the function at run time. However, since closures do this at compile time it should be in your opcache cache and therefore should not matter.
In terms of the performance impact of constructing a service using a factory vs closure firstly you have to remember that the service will only ever be constructed once per request regardless of how many times you ask for the service. I ran a quick benchmark of fetching a service using a closure and a factory and here is what I got (I ran a few times and all of the results were about the same value):
Closure: 0.026999999999999ns
Factory: 0.30200000000002ns
Those are nanoseconds, i.e 10-9 seconds. Basically the performance difference is so small that there is no effective difference.
Also ZF2 can't cache my whole module's configuration with closures. If I use purely factories then my whole configuration can be merged, cached and a simple file can be read on each request rather than having to worry about loading and merging configuration files every time. I've not measured the performance impact of this, but I'd guess it is marginal in any case.
However, I prefer factories for mainly readability and maintainability. With factories you don't end up with some massive configuration file with tons of closures all over the place.
Sure, closures are great for rapid development but if you want your code to be readable and maintainable then I'd say stick with factories.

breeze memory management - pattern / practice?

I have an old SL4/ria app, which I am looking to replace with breeze. I have a question about memory use and caching. My app loads lists of Jobs (a typical user would have access to about 1,000 of these jobs). Additionally, there are quite a few lookup entity types. I want to make sure these are cached well client-side, but updated per session. When a user opens a job, it loads many more related entities (anywhere from 200 - 800 additional entities) which compose multiple matrix-style views for the jobs. A user can view the list of jobs, or navigate to view 1 job at a time.
I feel that I should be concerned with memory management, especially not knowing how browsers might deal with this. Originally I felt this should all be 1 EntityManager and I would detachEntities when user navigates away from a job, but I'm thinking this might benefit from multiple managers by intended lifetime. Or perhaps I should create a new dataservice & EntityManager each time the user navigates to a new hash '/#/' area, since comments on clear() seems to indicate that this would be faster? If I did this, I suppose I will be using pub/sub to notify other viewmodels of changes to entities? This seems complex and defeating some of the benefits of breeze as the context.
Any tips or thoughts about this would be greatly appreciated.
I think I understand the question. I think I would use a multi-manager approach:
Lookups Manager - holds once-per session reference (lookup) entities
JobsView Manager - "readonly" list of Jobs in support of the JobsView
JobEditor Manager - One per edit session.
The Lookups Manager maintains the canonical copy of reference entities. You can fill it once with a single call to server (see docs for how). This Lookups Manager will Breeze-export these reference entities to other managers which Breeze-import them as they are created. I am assuming that, while numerous and diverse, the total memory footprint of reference entities is pretty low ... low enough that you can afford to have more than one copy in multiple managers. There are more complicated solutions if that is NOT so. But let that be for now.
The JobsView Manager has the necessary reference entities for its display. If you only displayed a projection of the Jobs, it would not have Jobs in cache. You might have an array and key map instead. Let's keep it simple and assume that it has all the Jobs but not their related entities.
You never save changes with this manager! When editing or creating a Job, your app always fires up a "Job Editor" view with its own VM and JobEditor Manager. Again, you import the reference entities you need and, when editing an existing Job, you import the Job too.
I would take this approach anyway ... not just because of memory concerns. I like isolating my edit sessions into sandboxes. Eases cancellation. Gives me a clean way to store pending changes in browser storage so that the user won't lose his/her work if the app/browser goes down. Opens the door to editing several Jobs at the same time ... without worrying about mutually dependent entities-with-changes. It's a proven pattern that we've used forever in SL apps and should apply as well in JS apps.
When a Job edit succeeds, You have to tell the local client world about it. Lots of ways to do that. If the ONLY place that needs to know is the JobsView, you can hardcode a backchannel into the app. If you want to be more clever, you can have a central singleton service that raises events specifically about Job saving. The JobsView and each new JobEditor communicate with this service. And if you want to be hip, you use an in-process "Event Aggregator" (your pub/sub) for this purpose. I'd probably be using Durandal for this app anyway and it has an event aggregator in the box.
Honestly, it's not that complicated to use and importing/exporting entities among managers is a ... ahem ... breeze. Well worth it compared to refreshing the Jobs List every time you return to it (although you'll want a "refresh button" too because OTHER users could be adding/changing those Jobs). You retain plenty of Breeze benefits: querying, validation, change-tracking, batch saves, entity navigation (those reference lists work "for free" in Breeze).
As a refinement, I don't know that I would automatically destroy the JobEditor view/viewmodel/manager when I returned to the JobsView. In my experience, people often return to the same Job that they just left. I might hold on to a view so you could go back and forth quickly. But now I'm getting tricky.

Using IoC, can a Singleton be injected with objects having a Transient Lifetime?

We have an ASP.NET MVC app using IoC to inject Service references into controllers and Repository references into Services.
Controllers have to have a Lifetime of Transient as they must be instantiated per request. If the whole IoC stack is being newed-up per request, though, this gets to be a bit of overhead. We have more dependencies than I'd like, and one option would be to have more controllers, each with fewer dependencies in the stack. But, leaving that aside for now, my question is, if an object that is injected as a singleton has dependencies that have a transient lifetime, will those dependencies essentially be treated like singletons by virtue of being owned by the Singleton?
Specifically, if we have the following
RepositoryA (needs to be transient because current design injects a user context in constructor)
ServiceA (singleton)
ControllerA (transient)
instantiated like so:
public ServiceA(IRepositoryA repo) {}
public ControllerA(IServiceA service) {}
Will RepositoryA essentially be instantiated once because ServiceA is instantiated once?
I'm 99% sure the answer is yes, but just wanted to confirm the amount of refactoring I have to do here.
Also, assuming Services and Repositories did NOT have any user/request-specific instance variables, as a design approach, is there any reason not to use a Singleton lifetime for them?
if an object that is injected as a singleton has dependencies that
have a transient lifetime, will those dependencies essentially be
treated like singletons by virtue of being owned by the Singleton?
That's correct. Since such component holds on to its dependencies (by storing their reference in a private field), those dependencies will live as long as the component itself does. In other word, their lifetime is implicitly promoted to the lifetime of the component (if their lifetime is shorter).
If you have this, your DI configuration is most certainly wrong and sooner or later this bug will show up. Probably only in production and hardly ever on your dev machine :-S.
In general all components managed by the container should only depend on abstractions that have a lifespan that is equal or longer than that of the component itself.
Some frameworks even have analysis services in place to detect these kinds of configuration errors. Nonetheless, you should be very careful when wiring up all dependencies. In general it would be safest to configure components as transient whenever possible, since a transient components is allowed to contain dependencies of any lifestyle. Having many transient objects would normally not be a performance problem. Building a rather large object graph per web request would typically be fast enough (otherwise try switching to a DI framework with a higher throughput).

Resources