I have the need to create a nested StructureMap container per Task. How does StrucureMap track nested containers? Is it safe to have a nested container per Task, or should I attempt to instantiate all required services outside the Task and then inject the service instance? I will be using the async / await features of C# inside each Task and I want to ensure that the specific containers will always resolve back to the same instance and not be shared across Task boundaries.
Related
I'm trying to have a better understanding of the lifetime of objects in DI by the point of view of an webapp. I'm using Unity Container docs here.
Singleton
Singleton lifetime creates globally unique singleton. Any Unity
container tree (parent and all the children) is guaranteed to have
only one global singleton for the registered type.
Now, because I've read so many articles, I've come to understand that Singleton is a instance that is created once and used for the entire life of application. What does this mean having in mind that 2 users use my app in the same time(or not) from different PCs - does this mean that if this instance is a variable, it will be common for all users for the entire time my app is hosted on the server (or until app App Pool Recycle)?
In my app I use different services that are injected in the controllers constructor.
Will Singleton be suited for an instance of a log service, or a DbContext instance?
If I use it for a DbContext instance, and something get's modified in the my Db structure - this instance will update?
Per Container
Per Container lifetime allows a registration of an existing or
resolved object as a scoped singleton in the container it was created
or registered. In other words this instance is unique within the
container it was registered with. Child or parent containers could
have their own instances registered for the same contract.
Same case: If 2 users use my app in the same time and visit same Controller, does this mean that they share the same instance of a Per Container variable/service?
Hope these questions have some meaning and I don't simply overthink it. Thank you!
Imagine you inject a single database connection to a handful of service classes. They now share what's essentially a global mutable state. How do DI frameworks deal with this? Do they:
Freeze the dependency before injection?
Only share immutable objects?
Wrap each dependency in a decorator to only provide exactly what's dependent on?
I tried searching for this and am a bit surprised I didn't find much. Feel free to provide links.
Related: https://en.wikipedia.org/wiki/Principle_of_least_privilege
Most DI containers provide the feature of registering a dependency within a Lifetime. For instance in .net core DI you can register a service with three different lifetimes:
Singleton: There is only one single instance. All the consumers of that service will use that instance. If one consumer changes the state of that dependency, all the other consumers will see that change.
Scoped: There is one instance per scope, where a scope is a web request. If a consumer changes the state of a scoped service, all the other consumers that will run in the same web request will see the change.
Transient: Each consumer uses a different instance of the service.
Always in .net core, the DBContext is (by default) added as a scoped service, this means that in the same web request all the consumers will use the same instance and this is useful when you need to run a transaction across different consumers (or better across different repositories).
I followed this links. https://dontcodetired.com/blog/post/Azure-Functions-Dependency-Injection-with-Autofac
Autofac Binding at Runtime
It worked fine. I want to know when azure function scales, object injected into azure function will be shared by all the instances of azure function. In this case object is NaiveInvestmentAllocator.
Let me know if you have any doubt. Also I actually implemented combination of two links. It is like factory pattern is used to get the object of instances from Autofac container. I can share the code if anyone want But I dont think that necessary.
My question is if I implemented first link, injected object is shared by all instances of same azure function or not?
Nope.
As Azure Functions scale, the other instances run on different VMs/Containers. Its similar to running your function app on different VMs/Containers manually.
If the requirement is to have a shared state across multiple function app instances, you should offload the state persistence to something like Redis, Table Storage, Blob Storage, etc.
For example, you can use Azure Cache for Redis for example and inject a client for the same into your service class.
If the intention is to save the number of open connections, note that the limit is per instance.
I am building an ASP.NET MVC 5 application using the repository and service layer design patterns. I have used unity to inject my services into my controllers.
This works nicely and until now I have not had a need to consider instantiating any objects requiring injection of interfaces outside my controllers. However I have a need for this when configuring my application startup to setup some users in the database.
For this I wanted to user my UsersService that I've built. And it occurred to me as the application grows there will surely be other occasions when I'll want to do the same, such as calling a service from within another service.
I see that I can instantiate a Unity container and call resolve on it to get my new instance of a service:
IProductService productService = container.Resolve<IProductService>();
However this kinda smells to me, having the container leaked all over my application seems like an anti pattern. So is there a better way to do this?
Unity and other dependency injection containers automatically do this. When you inject a service into a controller, it will automatically resolve the entire dependency graph of that service. Not only can you resolve dependencies of the service and its dependencies, you should inject dependencies into the service that needs them instead of the controller.
Any class (including the controller) that has more than a handful of dependencies is a code smell that you are violating the Single Responsibility Principle, and you most likely should refactor to aggregate services.
And yes, injecting the container to any point outside of the composition root is an anti-pattern called a service locator.
As for injecting services outside of the controller, it is important to distinguish between injectables and runtime data. For example, some try to inject services into DTO objects, attributes, static classes/extension methods, and other places where it is anti-pattern for services to be injected. For these situations, it is important to properly assess the situation and refactor toward a DI-friendly solution - favoring constructor injection over other alternatives and considering a service locator as a last resort. For example, if you are trying to make an extension method with a dependent service, most likely you have some functionality that itself should be a non-static service, DTOs should never be created from a DI container, and you may have to make use of more than one extension point in MVC where you inject the container within the composition root of the application, which does not constitute a service locator.
Is it worth it? Usually. What is gained? You gain the ability to change the application much more quickly than if you have a tightly-coupled application in ways that the designer of the application may not have even anticipated. So the extra cost of ensuring the application is loosely-coupled is usually more than recouped in ongoing maintenance of the project. As a side benefit, you gain the ability to easily unit-test each component independent of the others.
OK, I wired up StructureMap to my Web Api application (plenty of samples how to do this here on StackOverflow and elsewhere on the Internet). My understanding of object lifetime maintenance in Web Api is that it's done via nested containers.
For the whole idea of object lifetime maintenance via nested containers to work, Raven's session object would have to be created in child container as a transient singleton. Right now I have IDocumentStore defined in in parent container and scoped as singleton. IDocumentSession is also defined in parent container but scoped as HttpContext. When request comes in, BeginScope() is called, nested container is created but IDocumentSession object in it is inherited from the parent instead of being created.
I don't understand how this is supposed to work. If object is not created in child container as a transient singleton but is inherited from the parent instead then it will go back to the parent when nested container is disposed. This then defeats the whole idea. If on the other hand session is to be created in nested container as a transient singleton then how this can be accomplished? How can I verify the correctness of such setup?
If I set IDocumentSession as Per Web Request then why the need for
nested containers in the first place?
There is no need for nested containers in that scenario.
The need for nested containers by itself in general is even doubtful. Even the designer of Castle Windsor (a container that supports child containers) is considering to remove support for child containers in the next version of Castle Windsor all together.