Think of a scenario where we want more than one instance of a given service, or the decision, whether to instantiate a component is made at run time. For such scenarios injecting a service as a Direct or Lazy dependency will not be enough. However, injecting the service dependency as a Func do.

 

Using Func <T>

Consider the following example, where we have a PaymentProcessor class. The PaymentProcessor class has dependency on the IPaymentGateway service. And, the decision whether to instantiate the payment gateway or not, is based on the user’s choice of PaymentMode (say cash or card). The below code shows the use of a Func in this scenario:

 

It is important to note that there can be a scenario where a user chooses to pay in cash. In this case, we don’t need to instantiate IPaymentGateway. Also, we shall have a new instance of  IPaymentGateway, every time we initiate a new payment transaction.

 

Register & Resolve

The registration of the components will be quite simple and will be as shown in below code:

 

Because the IPaymentGateway has been registered as a Func, the container will not resolve it with  the PaymentProcessor. In fact, the container leaves it up to the PaymentProcessor to initialize IPaymentGateway using the auto-generated factory method. Therefore, as we can see in the above code, we are initializing the IPaymentGateway using the _paymentGatewayInitializer.

 

Lifetime Scope

In the above example, we have registered the IPaymentGateway as InstancePerLifetimeScope(). This is to say that, every time we call the Func<IPaymentGateway> we will get a new instance of IPaymentGateway. However, if we register a component as SingleInstance() and call Func<T> multiple times we will get the same object instance every time.


Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.