简体   繁体   中英

How to handle object configuration with Spring.NET

I'm using Spring.NET to wire up a medium-complexity WPF application. One of the objects represents the configuration settings of the environment the application runs on. The class, named MachineData , is basically a cache for values stored across the host machine: it checks whether a specific MSSql instance is installed and gets some values from there, it checks whether another specific program is installed and gets some of the app.config settings from there, etc. These values are required by many other objects within the application, but only need to be retrieved once, at application startup.

I have the MachineData object and all objects using it defined as follows for Spring.NET:

<object id="MachineData" type="IMachineData, SomeProject" singleton="true"/>

<object id="SomeOtherObject">
  <constructor-arg name="data" ref="MachineData"/>
</object>

<!-- A bunch of other objects w/ dependencies -->

<object id="MainApp" type="MainApplication">
  <property name="OtherObject" ref="SomeOtherObject"/>
  <!-- and so on -->
</object>

In MachineData.cs , I have:

public MachineData()
{
    Init();
}
private void Init()
{
    // Query database for settings, check app settings of other applications
}

And in App.xaml.cs :

var ctx = ContextRegistry.GetContext();
MainApplication mainApp = (MainApplication)ctx.GetObject("MainApp");

Which works perfectly fine, but would it be preferable to do the following:

// in MachineData.cs
public MachineData()
{
}
public void Init()
{
    // Query database for settings, check app settings of other applications
}


// in App.xaml.cs
var ctx = ContextRegistry.GetContext();
MainApplication mainApp = (MainApplication)ctx.GetObject("MainApp");
var data = (IMachineData)ctx.GetObject("MachineData");
data.Init();

Both would have the same desired effect, however the first option introduces more points of failure into the ContextRegistry.GetContext() call, while the second one requires exposing Init() to the IMachineData interface. Where should this initialization logic be handled?

Configure the machineData instance as singleton in your configuration; this means it will get created on container creation. In the MachineData configuration, define Init as the initialization method , or let MachineData implement IInitializingObject . For the latter, you need to take an explicit dependency on Spring.net.

Your app start up code would become

// in App.xaml.cs
var ctx = ContextRegistry.GetContext();
MainApplication mainApp = (MainApplication)ctx.GetObject("MainApp");

// not needed; called by the spring container:
// var data = (IMachineData)ctx.GetObject("MachineData");
// data.Init();

// ...

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM