Если это возможно, я бы рекомендовал избегать шаблона локатора службы и вместо этого вводить зависимость через конструктор:
public abstract class MyBaseClass<T> where T : class
{
public MyBaseClass(T instance)
{
Instance = instance;
}
public T Instance { get; }
}
Это позволит вам использовать ваш пакет через любую "основную" точку входа (например MVC или WebAPI), который вы выбираете.В этот момент потребитель должен будет обеспечить необходимую стратегию разрешения зависимостей.
Вот пример того, как потребитель (в данном случае служба WebAPI) пакета будет реализовыватьприведенный выше код:
public class MyWebApiClass : MyBaseClass<MyDependency>
{
public MyWebApiClass(MyDependency resolvedDependency) : base(resolvedDependency) { }
}
public class MyDependency
{
public string Foo { get; set; }
public MyDependency()
{
Foo = "Bar";
}
}
Тогда служба-потребитель также регистрирует эти зависимости:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddTransient<MyDependency>();
services.AddTransient<MyWebApiClass>();
}
... и внедряет при необходимости, что позволяет инфраструктуре разрешать зависимости (IoC на работе):
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
private readonly MyWebApiClass _myWebApiClass;
public ValuesController(MyWebApiClass myWebApiClass)
{
_myWebApiClass = myWebApiClass;
}
// GET api/values
[HttpGet]
public ActionResult<IEnumerable<string>> Get()
{
return new string[] { _myWebApiClass.Instance.Foo };
}
}
Посылая вызов вышеупомянутой конечной точке GET, мы видим, что наш экземпляр разрешается в MyBaseClass
: