JasperFx / lamar

Fast Inversion of Control Tool and Successor to StructureMap
https://jasperfx.github.io/lamar
MIT License
568 stars 119 forks source link

AddAllTypesOf - Open Generics #172

Closed cheng93 closed 5 years ago

cheng93 commented 5 years ago

The following test is failing, but I think the behaviour did work in StructureMap

[Fact]
public void open_generic_scanning_2()
{
    var container = new Container(i => {
        i.Scan(s =>
        {
            s.AssemblyContainingType<type_scanning>();
            //s.WithDefaultConventions();
            s.AddAllTypesOf(typeof(IAnotherInterface<,>));
        });

        //i.For(typeof(IAnotherInterface<,>)).Add(typeof(AnotherInterface<,>));
    });

    container.GetInstance<IEnumerable<IAnotherInterface<Fizz, Buzz>>>()
        .OfType<AnotherInterface<Fizz,Buzz>>()
        .ShouldNotBeEmpty();
}

public interface IAnotherInterface<in X, Y> { }

public class Fizz { }

public class Buzz { }

public class AnotherInterface<X, Y> : IAnotherInterface<X, Y> { }

WhatDoIHave() produces the following

============================================================================================================================================
ServiceType                 Namespace                                    Lifecycle     Description                      Name                
--------------------------------------------------------------------------------------------------------------------------------------------
IAnotherInterface<X, Y>     Lamar.Testing.IoC.Acceptance                 Transient     new AnotherInterface`2()         anotherInterface    
--------------------------------------------------------------------------------------------------------------------------------------------
IContainer                  Lamar                                        Scoped        Current IContainer               IContainer          
--------------------------------------------------------------------------------------------------------------------------------------------
IServiceContext             Lamar                                        Scoped        Current IServiceContext          IServiceContext     
--------------------------------------------------------------------------------------------------------------------------------------------
IServiceProvider            System                                       Scoped        Current IServiceProvider         IServiceProvider    
--------------------------------------------------------------------------------------------------------------------------------------------
IServiceScopeFactory        Microsoft.Extensions.DependencyInjection     Singleton     Current IServiceScopeFactory     IServiceScopeFactory
--------------------------------------------------------------------------------------------------------------------------------------------
Scope                       Lamar.IoC                                    Scoped        Current Scope                    Scope               
============================================================================================================================================

So it looks like it is there (ish). I don't know whether it is the scanner not picking it up properly, or whether it just isn't resolving the type, or whether actually, this is the actual behaviour

If i uncomment i.For(typeof(IAnotherInterface<,>)).Add(typeof(AnotherInterface<,>)); in the container configuration

IAnotherInterface`2         Lamar.Testing.IoC.Acceptance                 Transient     new AnotherInterface`2()         anotherInterface 

appears in WhatDoIHave() and the test passes.

jeremydmiller commented 5 years ago

Let's start with the stock advice to be cautious about doing crazy shit with generics because folks tend to get way over their head very easily.

I'm not sure what you're expecting to happen here. You many be thinking of the ConnectImplementationsToTypesClosing method. The behavior is unchanged from StructureMap. You might wanna scan this document: https://jasperfx.github.io/lamar/documentation/ioc/generics/

cheng93 commented 5 years ago

Correct me if I am wrong, but the type I am trying to resolve is not closed?

As to what I am expecting, I'm hoping to resolve AnotherInterface<X,Y> class to the IAnotherInterface<X,Y> interface

jeremydmiller commented 5 years ago

This method: s.AddAllTypesOf(typeof(IAnotherInterface<,>)); -- does NOT work with open generics and does nothing magical to connect things. If all you want to do is automatically close and resolve the type AnotherInterface<X,Y> when you ask for IAnotherInterface<X,Y>, then all you need to do at registration time is this:

For(typeof(IAnotherInterface<,>)).Add(typeof(AnotherInterface<,>));
cheng93 commented 5 years ago

And if had multiple open implementations of IAnotherInterface<,> I would need to register them each manually?

If it's yes, and their is no plans of implementing the feature, then I guess this can be closed.

jeremydmiller commented 5 years ago

Yes, and I have no intention of extending the add all types thing. Feel free to do a PR though if you want to. It's never been a high priority because the Connect** is what most folks actually want.

cheng93 commented 5 years ago

Any pointers on where to start

jeremydmiller commented 5 years ago

Just find that method, then the IRegistrationConvention that it's attached to

jeremydmiller commented 5 years ago

No recent activity, closing this.