I'm trying to use Castle Windsor to reuse a single instance of my WebApp settings class ( MySettings
). This settings rarely changes, but when it changes, I need to update the instance in the container. I can easily track when the Settings changes, but I can't figure out the right way to do it, can anybody help me?
The Windsor Installer class is bellow:
public class SettingsInstaller : IWindsorInstaller
{
private MySettings Settings { get; set; }
public void Install(IWindsorContainer container, IConfigurationStore store)
{
UpdateSettings();
container.Register(
Component.For<MySettings>()
.Instance(this.Settings));
}
public MySettings UpdateSettings()
{
using (DbContext db = new DbContext())
{
this.Settings = db.Settings.FirstOrDefault();
}
return this.Settings;
}
}
How can I call the UpdateSettings()
and make sure that the container will use the updated Settings
in the next Dependency Injection resolution?
I had no answer yet. I have done this, and it is working:
public class SettingsInstaller : IWindsorInstaller
{
private static MySettings Settings { get; set; }
public void Install(IWindsorContainer container, IConfigurationStore store)
{
UpdateSettings();
container.Register(
Component.For<MySettings>()
.UsingFactoryMethod(() =>
{
return SettingsInstaller.Settings;
})
.LifestyleTransient());
}
public static MySettings UpdateSettings()
{
using (DbContext db = new DbContext())
{
SettingsInstaller.Settings = db.Settings
.AsNoTracking()
.FirstOrDefault();
}
return SettingsInstaller.Settings;
}
}
I think what you want is for MySettings to be a singleton whose state you can then update in other parts of the application. If you register MySettings as a singleton, then whenever the container resolves a MySettings for you, it will return the same instance. This is essentially what you are doing in your answer, but you're just storing the instance in a local variable (instead of letting the container do it for you).
Your registration code can then get very simple:
public class SettingsInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(Component.For<MySettings>().LifestyleSingleton());
}
}
Whenever you need to access the settings, you can request a MySettings from the container using constructor injection (or any other method of getting an instance from a container):
public class ClientClass
{
private readonly MySettings _settings;
public ClientClass(MySettings settings)
{
_settings = settings;
}
public void UpdateSettings()
{
_settings.SomeSetting = myNewSetting; // reset them however you need to here
}
}
After you've called UpdateSettings() in your application somewhere, then the instance the container is holding on to (a singleton) will be updated with myNewSetting, and when the next class requests a MySettings you'll get the same instance with the updated value.
If you actually need a new instance of MySettings, then in your UpdateSettions() method you can create an entirely new one using _settings = new MySettings()
and the container will serve up the new instance for you from then on.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.