代码之家  ›  专栏  ›  技术社区  ›  wydy

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

  •  0
  • wydy  · 技术社区  · 6 年前

    我用创建了一个项目。净核心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 回复  |  直到 6 年前
        1
  •  0
  •   wydy    6 年前

    我在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;
                });
         }
    }