Search code examples
dryioc

How to register IEnumerable<IService> In DryIoc Mvc Controller like Autofac Enumeration (IEnumerable<B>, IList<B>, ICollection<B>)


Test Code With Autofac is Ok,but with DryIoc is error. How to make this work.

public class HomeController : Controller
        {
            private readonly ITestAppService _testAppService;
            private readonly IEnumerable<ITestAppService> _testAppServiceList;
            public HomeController(ITestAppService testAppService, IEnumerable<ITestAppService> testAppServiceList)
            {
                _testAppService = testAppService;
                _testAppServiceList = testAppServiceList;
            }
    }
public class Test1AppService : ITestAppService{}
public class Test2AppService : ITestAppService{}
public interface ITestAppService: IAppService{}

The error 'Make sure that the controller has a parameterless public constructor ' is caused by field ITestAppService in controller not the field IEnumerable.Following is my register code.

var impls =
                typeof(IAppService).Assembly
                .GetTypes()
                .Where(type =>
                type.IsPublic && 
                !type.IsAbstract && 
                type.GetInterfaces().Length != 0 && typeof(IAppService).IsAssignableFrom(type));

            foreach (var type in impls)
            {
                container.Register(type.GetInterfaces().First(), type, Reuse.Transient);

            }

Resolved by dadhi's suggestion,My container is

DryIoc.IContainer container = new DryIoc.Container(
                rules =>
                {
                    return rules.WithFactorySelector(Rules.SelectLastRegisteredFactory())
                    .WithResolveIEnumerableAsLazyEnumerable();
                }
            );

The dryioc wiki about Resolving from multiple default services may need some update. Rules.SelectLastRegisteredFactory is a method.


Solution

  • The problem is that consdering two implementations of ITestAppService container doesn't know which to select for the first dependency. But you may explicitly define the convention:

    var container = new Container(rules => rules
        .WithFactorySelector(Rules.SelectLastRegisteredFactory));