In Simple Injector, why is this an error for a singleton or scoped service, which depends on temporary maintenance

I am using a simple injector 3.0.4

I have a service that with a lifestyle depends on a service that has a transitional lifestyle.

When I call container.Verify (), I get a diagnostic error about image mismatch.

The temporary service causing the problems is introduced into other temporary services, so before I go ahead and do my whole project, I need to ask. Why dependence on the scale of any lifestyle before the transitional issue? Transients are updated every time they are introduced, so nothing else can stop it. Essentially, the lifetime of a transitional object is determined by the service into which it is introduced.

Also, I already read the documentation on this issue from here , and I understand why you do not want the singleton to depend on for example, but, of course, the dependence on the transition process is always safe?

+6
source share
1 answer

Transients are updated every time they are introduced, so nothing can interfere with it.

Transients are updated every time you request them from the container, but after they are entered into the component, they will stick until this component lives on. Therefore, if the consuming component is single, this means that it will pull along all its dependencies, which makes them almost the same. This behavior becomes apparent if you look at how you usually implement dependency injection:

public class SomeComponent { private readonly ILogger logger; private readonly IService service; public SomeComponent(ILogger logger, IService service) { this.logger = logger; this.service = service; } } 

As you can see, dependencies are stored in the private fields of the component, they will remain alive as long as SomeComponent lives, and SomeComponent will continue to use the same dependencies.

Essentially, the lifetime of a transitional object is determined by the service into which it is introduced.

Smooth; component lifestyles will be at least longer than its consumer. However, several consumers with different lifestyles can have an addiction, which makes it really hard to understand how long the addiction will live. When introduced to consumer 1, he can live for the entire time of the request, while another instance of this dependency introduced in consumer 2 will live as long as the application does.

Like scope instances, transient registrations are usually not thread safe; otherwise you would register them as singleton. Saving transients for a longer period of time can obviously cause concurrency errors or errors related to outdated data. This is why Simple Injector prohibits this by default and throws an exception.

You may be confused about how Autofac defines its lifestyle compared to Simple Injector. Autofac does not contain a transitional lifestyle. Instead, it has an InstancePerDependency style. Technically, this is the same as transitional, but the intention is very different. Using InstancePerDependency you say: "This component is designed to live as long as its consumer, no matter how this lifestyle is." There are times when it makes sense, but by doing this you actually ignore the elephant in the room, and I saw that the lack of detection is a common source of errors. In most cases, if you do not care about the style of the components, this means that it should be registered as singleton - not InstancePerDependency .

The reason Simple Injector doesn’t allow transients to be introduced into instances with scope is because objects with scope can live for a long time (depending on the application), and you cannot always assume that transients can be safely entered for Reached consumers.

In the end, it's all about conveying the intentions of your code. If the component is static or thread safe, you must register it as singleton. It is not thread safe, you are registering it as limited or transient. This makes it clear to everyone who reads the configuration how it should handle such a component. And it allows Simple Injector to detect any wrong configuration for you.

While Simple Injector detects the wrong configurations for you, I have come to the conclusion that your DI configuration can be greatly simplified when your system is designed around object graphs consisting solely of single-element components. I expressed these thoughts here . This will eliminate many of the difficulties we encounter when working with dependency injection, and even detect a violation of SOLID principles even faster than DI itself does.

before I continue and complete the entire project

This is what I would not recommend doing. Usually you see that only some of the "leaf components" in your application are limited (for example, DbContext ). Limited coverage components are independent of many other components. Components that you write yourself should usually be idle and not need to be cached. Therefore, in the event that Singleton graphic objects are (not yet) an option, I would usually do as much of the object's timeline as possible, and only those few sheet components covered by the area. Since transients can safely depend on instances with scope, everything will work as expected.

+10
source

All Articles