jeudi 27 mai 2021

Best way to using static container instead a lot of singleton class...can you show me some example? [closed]

I have a legacy winForms application that now i'm in charge of maintaining and developing. This app has a lot of singleton instance in all the code that rappresent the component used by the application. Some are very similar to service that wrap other component or other class. Other instead wrap some entities to making a cache-like pattern

This is an example of this cached class

public class SingletonCycle
{
    private static Cycle _instance;
    private static DevExpress.RackManager.RackManager _rackManager;

    public static event EventHandler<Cycle> OnCycleUpdated;

    private static void RaiseOnCycleUpdated(Cycle cycle)
    {
        OnCycleUpdated?.Invoke(cycle, cycle);
    }

    public static Cycle GetInstance()
    {
        return _instance;
    }
    
    public static void SetCycleInstance(Cycle cycle)
    {
        if (_instance != null)
        {
            SingletonAuditTrail.GetInstance().ModifiedCycle(cycle);
        }
        else
        {
            SingletonAuditTrail.GetInstance().StartCycle(cycle);
        }
        _instance = cycle;
        _instance.CreationDate = DateTime.Now;
        _instance.Operator = CommonUIManager.GetInstance().GetConfig().GetCurrentUser;

        SaveCycle();
    }
}

I want to try to start a refactor by using Di and Simpleinjector. Because i want to begin to test some part of the software Basically i want to trasform all this singleton in service that will be registered in container as singleton.

The problem is that all this services are spread out in all the software and for now i can't use everywhere constructor injection because i can't put all the classes inside container.

For now I try to use the container as static and everywhere use it instead of every singleton instances I now that it's not good to spread out static container everywhere and using container as static but i don't have any other clue on how to do this

Register container in the static Main

public static Container Container { get; private set; }

static void Main()
{
........
    var crpConfig = SingletonCrpCompactConfig.GetInstance();
    var container = new Container();
    
    container.Register(typeof(UnitOfWorkManager),
        CreateUOWManager(crpConfig),
        Lifestyle.Singleton);
    container.Register(typeof(RecipeModuleCache),
        CreateRecipeModuleCache(crpConfig, container),
        Lifestyle.Singleton);
        container.Verify();
    Container = container;
......
}

private static Func<object> CreateRecipeModuleCache(CrpCompactConfig crpConfig, Container container)
{
    return () =>
    {
        var uowManager = container.GetInstance<UnitOfWorkManager>();
        var cache = new RecipeModuleCache(crpConfig, uowManager);
        return cache;
    };
}

Example of the service to be registered inside the container

public class RecipeModuleCache
{
    private readonly CrpCompactConfig _config;
    private readonly UnitOfWorkManager _uow;
    private CrpCompactRecipeModule _instance;
    private bool _cached;

    public RecipeModuleCache(CrpCompactConfig config, UnitOfWorkManager uow)
    {
        _config = config;
        _uow = uow;
    }

    public CrpCompactRecipeModule GetCached()
    {
        if (_cached)
            return _instance;
        _instance = StaticBuilders.Create(_uow);
        _cached = true;
        return _instance;
    }

    public void Invalidate()
    {
        _instance = null;
        _cached = false;
    }
}

After this registration where there is the singleton i use instead

Program.Container.GetInstance<RecipeModuleCache>()

There is some problem of using this kind of patterns instead static singleton

Can you suggest some other advice?

Aucun commentaire:

Enregistrer un commentaire