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

Allow open generics to be included in AllClasses scan #42

Closed
bordecal opened this issue Feb 27, 2018 · 8 comments
Closed

Allow open generics to be included in AllClasses scan #42

bordecal opened this issue Feb 27, 2018 · 8 comments
Milestone

Comments

@bordecal
Copy link

At present, open generics are excluded from an <assembly>.AddClasses scan (via ReflectionExtensions.IsNonAbstractClass, which considers a concrete open generic to be abstract). The container supports registration of open generics, so it's a little puzzling why this limitation is in place. It would be lovely to be able to include open generic registration in a scan something like the following:

services.Scan(s => s
                .FromAssembliesOf(assemblyMarkerTypes)
                .AddClasses(new ClassOptions() { NonPublic = true, OpenGeneric = true })
                .AsImplementedInterfaces()
                .WithTransientLifetime());
@khellang khellang added this to the v2.2.0 milestone Feb 27, 2018
@khellang
Copy link
Owner

I've pushed v2.2.0 with support for open generic scanning to NuGet.

@bordecal
Copy link
Author

bordecal commented Mar 1, 2018

Many thanks for the quick change! One little note... If one is including non-public classes in the scan, nested private classes will also be picked up. This isn't usually a problem, but it can be in some special cases. I ran into one of these after updating to v2.2.0, which was related to the nested classes generated by the compiler for async methods. These implement IAsyncStateMachine, and the container was attempting to resolve one of the private classes to satisfy this interface.

The problem is trivial to avoid via use of the AddClasses(Action<IImplementationTypeFilter>, Boolean) overload, so I doubt that it would be necessary to add functionality specifically to avoid the nested classes by default (unless you end up with a lot of issues/questions because of this 😕), but it might be worth adding a note to the readme and/or other docs to help folks understand the problem when it does occur.

Thanks again!

@khellang
Copy link
Owner

khellang commented Mar 1, 2018

This isn't usually a problem, but it can be in some special cases. I ran into one of these after updating to v2.2.0, which was related to the nested classes generated by the compiler for async methods. These implement IAsyncStateMachine, and the container was attempting to resolve one of the private classes to satisfy this interface.

Hmm. Those should probably don't be included anyway. I think I should add a filter for classes with the CompilerGeneratedAttribute.

but it might be worth adding a note to the readme and/or other docs to help folks understand the problem when it does occur.

Yes, I was thinking about bumping this version to 3.0 because of the potential of breaking people with this change, but decided against it. Might be a nice middleground to add a note to the readme.

@khellang
Copy link
Owner

khellang commented Mar 1, 2018

Pushed v2.2.1 which excludes compiler-generated types from scanning 😄

@bordecal
Copy link
Author

bordecal commented Mar 5, 2018

Thanks! It's working perfectly.

@NeoXtreem
Copy link

Pushed v2.2.1 which excludes compiler-generated types from scanning 😄

@khellang This issue seems to still be happening in .NET Core 3.0. I'm using the following code:

services.Scan(s => s.FromCallingAssembly().AddClasses(false).AsImplementedInterfaces());

An internal class with an async method is then causing an IAsyncStateMachine type to be registered.

Is this a new issue because perhaps CompilerGeneratedAttribute is not being used in .NET Core 3.0, or am I doing something wrong?

Also, speaking of excluding unwanted types, you may be able to help also with this related question on SO.

@khellang
Copy link
Owner

Hi @NeoXtreem! 👋

It could be an issue that the type doesn't have CompilerGenerated on it, or maybe I just have to include a filter for IAsyncStateMachine as well.

Could you open a new issue with a bit more information about the type?

@NeoXtreem
Copy link

OK, I've raised issue #108. It appears it happens on C# closures.

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

3 participants