Easy registration of injector changes at runtime

I am using Simple Injector with an ASP.NET Web API project, and I want to use different implementations for the same interface, depending on the version of the REST endpoint used. For example, if v1 is used as an endpoint, it IPaymentDatamust be created with a class named PaymentData, but if v2 is used IPaymentData, it must be implemented by a class called PaymentDataNew. This turns out to be problematic!

I do not want to use a composite class as part of the Simple Injector documentation, because this means that my code should be aware of and take into account the deployment infrastructure that I use (bad).

In the latest version (3.0), I noticed something called "Context Based" . Using a function container.RegisterConditional, you should be able to run a delegate every time a type is resolved.

container.RegisterConditional(typeof(IPaymentData),
    c => ((HttpContext.Current.Items["version"] as string ?? "1") == "2") 
        ? typeof(PaymentDataNew) 
        : typeof(PaymentData),
    Lifestyle.Scoped,
    c => true);

This does not seem to work, because although the lifetime is limited, and the default lifestyle WebApiRequestLifestyle, the delegate that returns the implementation depending on the version is called only for the first request that comes. requests skip this (they seem to use a cached implementation).

Is there something I am missing? How can I make sure that a delegate is called every time a request arrives?

+4
source share
1 answer

, ,

. , DI. , Root of Composition. DI, , .

container.RegisterConditional , .

Simple Injector v3 RegisterConditional . , ( ). (IntelliSense/XML) :

; .

, . :

  • , , , , ,
  • .

(, version HttpContext). verify .

, , - IPaymentData, . ; , , DI.

-:

public sealed class HttpRequestVersionSelectorPaymentData : IPaymentData
{
    private readonly PaymentData paymentOld;
    private readonly PaymentDataNew paymentNew;
    public VersionSelectorPaymentData(PaymentData old, PaymentDataNew paymentNew) { ... }

    private bool New => HttpContext.Current.Items["version"] as string ?? "1") == "2";
    private IPaymentData PaymentData => this.New ? paymentNew : paymentOld;

    // IPaymentData method(s)
    public Payment GetData(int id) => this.PaymentData.GetData(id);
}

, ( ) , , .

+5

Source: https://habr.com/ru/post/1608833/


All Articles