具有更多实现和依赖注入的接口

时间:2018-04-13 14:31:29

标签: dependency-injection interface .net-core

我使用.net Core 2创建了一个项目。 现在我有一个来自运行时所需的相同接口的类列表。 我的问题是,我无法将此类添加到servicecollection(只有一个接口)。所以我无法访问这些类中的其他服务。我认为它不会解决它。

我可以使用我的servicecollection创建一个单例/静态类,并使用IServiceProvider从那里获取其他服务,但我认为这不是最好的做法。

这是我的问题的一个例子:

public class Manager : IManager
{
   private IList<IMyService> _myService;

   public Manager()
   {
       IList<Type> types = GetIMyServiceTypes();
       foreach (Type type in types)
       {
            var instance = (IMyService)Activator.CreateInstance(type);
            _myService.Add(instance)
       }
   }

    public IList<bool> IsTrue()
    {
        return _myService
            .Select(se => se.IsTrue())
            .ToList();
    }

   public IList<Type> GetIMyServiceTypes()
   {
       var type = typeof(IMyService);
       var types = AppDomain.CurrentDomain.GetAssemblies()
           .SelectMany(s => s.GetTypes())
           .Where(p => type.IsAssignableFrom(p))
           .ToList();

        return types;
   }
}

public class ServiceType1: IMyService
{
     public bool IsTrue()
     {
      //Need Access to IServiceCollection Services
     }
}

public interface IMyService
{
    bool IsTrue();
}

public class MyController : Controller
{
    private IManager _amanager;
    public MyController(IManager manager)
    {
         _manager = manager
    }

    public IActionResult IsTrue()
    {
         IList<bool> isTrue =_manager.IsTrue();
         return new ObjectResult(isTrue);
    }
}

是否有一种模式,我可以用来解决我的问题?是否有最佳做法是在构造函数中不使用它们来访问服务?

1 个答案:

答案 0 :(得分:0)

我在stackoverflow https://stackoverflow.com/a/44177920/5835745

中的另一篇文章中找到了解决方案

但我会针对同样的问题向其他人发布我的更改。我从配置中加载了类列表,但也可以添加所有类。

        public class Manager : IManager
        {
           private IList<IMyService> _myService;
           private readonly Func<string, IService> _serviceAccessor;

           public Manager (Func<string, IService> serviceAccessor)
           {
               IList<string> authentications = new List<string> {"value1", "value2"}
               foreach (string authentication in authentications)   
               {
                    AddAuthentication(_serviceAccessor(authentication));
               }
           }

            public IList<bool> IsTrue()
            {
                return _myService
                    .Select(se => se.IsTrue())
                    .ToList();
            }
        }

    public class Startup
    {
         public void ConfigureServices(IServiceCollection services)
         {
                services.AddTransient<Value1>();
                services.AddTransient<Value2>();

                services.AddTransient(factory =>
                {
                    Func<string, IService> accesor = key =>
                    {


           switch (key)
                    {
                        case "value1":
                            return factory.GetService<Value1>();
                        case "value2":
                            return factory.GetService<Value2>();
                        default:
                            throw new KeyNotFoundException(); 
                    }
                };
                return accesor;
            });
     }
}