Изменение времени выполнения контейнера Structuremap по умолчанию - PullRequest
0 голосов
/ 07 января 2020

У меня есть требование использовать реализации, определяемые арендатором c, которые переопределяют GlobalService.

public interface IService{ 
    void Process();   
}

[Service("Default")]
public class GlobalService: IService{   
   public virtual void Process(){...}
}

[Service("Tenant1")]
public class Tenant1Service: GlobalService {   
    public override void Process(){...} 
}

[Service("Tenant2")]
public class Tenant2Service: GlobalService {   
    public override void Process(){ base.Process() ...}  
}

Таким образом, GlobalService все GlobalService, Tenant1Service and Tenant2Service реализуют IService интерфейс.

С StructureMap Я зарегистрировал эти сервисы в различных профилях

GlobalService -> Default Profile
Tenant1Service -> Tenant1 Profile
Tenant2Service -> Tenant2 Profile

Мое приложение - ASP. Net Core 3.0 WebApi. Я могу успешно получить правильную реализацию сервиса с помощью:

 var profile = container.GetProfile("Tenant1");
 var instance = profile.getInstance<IService>(); // return Tenant1Service  

Что я хотел бы сделать, так это каким-то образом подключиться к каждому запросу и изменить Контейнер по умолчанию на Контейнер профиля (при необходимости, на основе параметров запроса) , но мне не удалось найти методы, такие как SetDefaultContainer, чтобы настроить его.

Я создал класс промежуточного программного обеспечения, поэтому могу вставлять и изменять контейнер, но он не работает:

public class StructureMapMiddleware
{
    RequestDelegate next;
    private readonly ILogger log;

    public StructureMapMiddleware(RequestDelegate next, ILoggerFactory loggerFactory)
    {
        this.next = next;
        this.log = loggerFactory.CreateLogger<StructureMapMiddleware>();
    }

    public async Task Invoke(HttpContext context, IContainer container)
    {
        container = container.GetProfile(context.Request.Headers["Tenant"]);

        await next(context);
    }
}

В моих контроллерах или других службах я просто хотел бы использовать инъекцию конструктора, например

public class MyController : Controller{
   public MyController(IService service){...}
}
...