New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Stateless / Automatic / Dynamic lifestyle #608

Open
dotnetjunkie opened this Issue Aug 20, 2018 · 2 comments

Comments

3 participants
@dotnetjunkie
Collaborator

dotnetjunkie commented Aug 20, 2018

Most registered components will, by themselves, contain no state, except the state implicitly 'inherited' from their dependencies.

This means that this component can get the same lifestyle as the shortest lifestyle of its dependencies. In case there are no dependencies, the component can become a singleton. In other words, their lifestyle can be implied an inherited from the dependencies.

Registering components with an 'automatic' lifestyle can optimize performance and reduce changes from being made when dependencies are introduced. When a scoped leaf dependency is introduced, it will cascade up through its consumers that will have their lifestyle 'lowered'.

To prevent this cascading, making object graphs transient is the simplest solution, but much less performant.

By letting Simple Injector know that "this component is stateless", Simple Injector can do the math for you.

Example:

var container = new Container();
container.Options.DefaultLifestyle = Lifestyle.Automatic;

container.Register<HomeController>(Lifestyle.Transient);
container.Register<CommerceContext>(Lifestyle.Scoped);

// uses 'auto' lifestyle
container.Register<IUserContext, AspUserContext>();
@TheBigRic

This comment has been minimized.

Collaborator

TheBigRic commented Aug 20, 2018

This sounds sophisticated. I like the idea very much, for advanced users....

I see however also some downsides. In order of coming to my mind:

  • How, in the given example, is guarenteed that the object contains no state? A user could easily trip if, by changing the default lifestyle to 'auto', SI assumes stateless services. So this has to be more than clear from the docs.
  • I think a seperate registation API as opposed to a different lifestyle is therefore a better solution. SI can use the 'auto lifestyle' under the covers ofcourse.
  • It seems to be a 'magic wand'. I remember the most difficult part to understand, when starting with DI, was lifetime management. Removing this from the user creates better managed applications at first, but does not educate users on the long term, because 'it just works'. In recent years MS put a lot of effort in creating templates for e.g. MVC which do just that: "just work". And you know how I think about these templates...

So to use this feature, you'll have to do an exam. Passing the exam gives you the lazy bastard lifestyle, failing the test... well we have to think about that one.

@onyxmaster

This comment has been minimized.

onyxmaster commented Nov 13, 2018

Occasionally stumbled on this one, let me add my two cents.
This could be very interesting for mass registration scenarios (for example an open generic implementation) where different implementations have different lifestyles.
For example, consider the command handler with ICommandHandler<TCommand> service type and several hundreds of its implementations. While we can always be on the safe side and use transient lifestyle for their registrations, in most of the cases the command handlers depend either on some service that performs the action (in case there is an application services layer), or on repository/store/whatever that is used to retrieve and persist state. Most often these services are singletons and the command handler itself could be a singleton too, but specifying singleton lifestyle for all command handler implementations seems a bit too much. This can be solved with, for example, attribute-based registration or some kind of external policy, but if you are considering dependency lifestyle analysis, this would be the best solution for this problem.

I surely do agree that automatic lifestyle should not be the default one, since it might break some things.
Actually, I'd eliminate any registration methods that do not accept explicit lifestyle (registering a transient-by-default caching decorator over a singleton service instance is something I did more than once for example), but that's neither a decision for me to make, nor a topic of this discussion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment