Skip to content
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

Can be done differently the implementation of the DependencyScope? #366

Open
scoppini opened this issue Nov 22, 2017 · 5 comments
Open

Can be done differently the implementation of the DependencyScope? #366

scoppini opened this issue Nov 22, 2017 · 5 comments

Comments

@scoppini
Copy link

Hi everyone,
I am writing a new web api application using Windsor. I've always used Microsoft Unity and Autofac. Now I want to try Windsor.
But something is not clear using Windsor. I have seen how everyone, all people, write the dependency resolver and the dependency scope.
Honestly, I do not like that way... It seems muddler to me... but perhaps because I have not understood something..
I try to explain what I mean talking about my experience with Unity and Autofac. The question I want to answer is: How do I start a new scope in "every" DI framework?

Microsoft Unity
In the dependencyResolver, inside the BeginScope method, I creat a childContainer and I call recursively the resolver:

var child = container.CreateChildContainer();
return new UnityResolver(child);

In this way, every service resolved in the child container will have the scope of the child container. The scopes of the child containers are the classic scopes: Singleton, PerWebRequest, ....

Autofac
In the dependencyResolver, inside the BeginScope method, I create a dependencyScope object that take as parameter a LifeTimeScope. Then, I resolve everyting in the lifeTimeScope:

new AutoFacDependencyScope(_container.BeginLifetimeScope());

Here, how resolve the service(s) in the AutoFacDependencyScope:
_lifetimeScope.TryResolve(serviceType, out instance);

As you can see, the services are resolved using the lifeTimeScope, not the container.

Windsor
Surely you know better than me how to implement the dependency resolver and the dependency scope. Here I write how I have done.
In the dependencyResolver, inside the BeginScope method, I create a dependencyScope object that take as parameter the SAME instance of the container I am using. Then, inside the dependencyScope i do a begin scope and I resolve the services in the container I passed from outside.
It looks like nothing changed... I am resolving everything inside the main container just with the difference that before I have called a begin scope... perhaps that is enough to create everything with a scope... but it is not explicit... I am just supponsing...

Is it correct this way?

@ghost
Copy link

ghost commented Nov 22, 2017

I have an open PR where I am trying to get this exact idea merged. You can see the implementation we are going for here. The PR is also #351.

@scoppini
Copy link
Author

scoppini commented Nov 22, 2017

Thank you for answer.. I look at it

@ghost
Copy link

ghost commented Jan 10, 2018

I have some further questions. Just trying to understand the question you ask when you say:

In the dependencyResolver, inside the BeginScope method, I create a dependencyScope object that take as parameter the SAME instance of the container I am using. Then, inside the dependencyScope i do a begin scope and I resolve the services in the container I passed from outside. It looks like nothing changed... I am resolving everything inside the main container just with the difference that before I have called a begin scope... perhaps that is enough to create everything with a scope... but it is not explicit... I am just supponsing...

Can you explain what lifestyles they were registered with? Singleton, Scoped or Transient? It will help me understand what your current setup is. Do you also mind posting a code sample for clarity?

@jonorossi and I have been talking about "Instances Per Matching Lifetime" scope from Autofac for this PR but I just need to be sure that is what you mean. I feel engaging the resolution mechanism from a scope for a container mutates the intent of the lifestyle for original registration of what that component was originally intended for when it comes to implementing IDisposable. It creates permutations around whether a singleton is in fact a singleton or whether it is a scoped singleton. I am sure you can appreciate these are fundamentally different.

Also in Windsor today, singletons are disposed when the container get's disposed. Are we saying that singletons get disposed when a scope is started, a singleton gets resolved and the scope get's disposed? If so, this changes the meaning of a singelton. I feel this is fundamentally wrong. Based on the original writings from "Gang of four" this should be a process wide lifestyle.

The implications of indicating intent via registation and then having their behaviour mutated via scopes are ugly. The AspNet team did this with their dependency injection abstractions for dotnet core. I cannot say I am happy with the result(I am not the only one), it also earned Windsor the title of a "non conforming container" which I thought was peculiar.

Look forward to your response, and code sample. Let's see how we can make this work.

@ghost
Copy link

ghost commented Mar 31, 2018

@scoppini - Have you had a chance to look at this? We have not released yet and would love to hear some feedback.

@ghost
Copy link

ghost commented Mar 31, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant