我使用.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);
}
}
是否有一种模式,我可以用来解决我的问题?是否有最佳做法是在构造函数中不使用它们来访问服务?
答案 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;
});
}
}