mardi 17 novembre 2020

Prototype objects and "Per Graph" DI Lifecycle

I've got a Credentials class that should be provided through dependency injection as an instance to all constructors which need it. Currently I've solved this problem by registering a single instance of the class to my DI container, with a singleton lifecycle. This ensures, per DI invocation, that all objects receive the same credentials. This works, but is a little awkward because the properties of the Credentials singleton will change between each explicit DI invocation. This means each recipient constructor must immediately "grab and save" credentials properties from the Credentials instance before they change.

What would make this better is if I could get the DI container to create a new Credentials instance, per-graph or per-invocation, that is based on a prototype object (yes, GOF "Prototype" pattern). I am using Simple Injector, so my first solution looks like this:

public static Credentials creds; //Implements ICloneable

//....

var prototypeTransientLifestyle = Lifestyle.CreateCustom(
    name: "Prototype Transient",
    // instanceCreator is of type Func<object>
    lifestyleApplierFactory: instanceCreator =>
    {
        return () => creds.Clone();
    });

I think this works but, even so, it has two weaknesses. First, it can only be applied to my Credentials class. I'd like it to be generically reusable. Second, it creates potentially many clones within a single, explicit DI invocation. I'd like it to have "per-graph" lifecycle so that it creates the clone just once and re-uses it for the remainder of that DI invocation.

Any ideas of how to proceed?

Incidentally, I know that "per-graph" lifecycle suffers from problems associated with lazy evaluation. I don't have any lazy evaluation, so it is not a concern.

Aucun commentaire:

Enregistrer un commentaire