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