现有应用程序基于MVVM Light,并使用autofac容器创建对象。在应用程序的生命周期中,需要使用新参数重建已经创建的对象。我对autofac经验不足
示例:
containerBuilder.RegisterType<SerialPortController>().Named<ISerialPortController>("ConveyorController").WithParameter(
new ResolvedParameter(
(pi, ctx) => pi.ParameterType == typeof(string) && pi.Name == "portName",
(pi, ctx) => ctx.Resolve<ISettingsModel>().ConveyorSerialPort)).SingleInstance();
例如,“ portName”被更改。 我对此没有很好的解决方案。有人有经验吗?
答案 0 :(得分:2)
您的代码段中有:
ISerialPortController
的{{1}}实现,已在应用程序中注册为单个实例。这意味着它将在Autofac容器的使用寿命(通常也是应用程序的使用寿命)中存活。SerialPortController
使用的值来自SerialPortController
。该模型中的设置可能会在应用程序过程中发生更改,并且ISettingsModel
进行此操作时需要开始使用新值。我将首先回答一个简单的问题:无法在Autofac中重新初始化单例。单例的优点和缺点是……这是一个单例。构建完成后,就完成了。您必须删除整个容器并重新构建它,才能重新构建单例。
还有其他方法可以解决该问题,尽管这些方法实际上不需要重新初始化单例。
将控制器设为SerialPortController
,而不是使控制器成为单例。它消耗的设置仅在单个实例处于活动状态时才会保留。
您可能希望将其设为单例,例如创建起来很昂贵,或者充当资源池之类的东西。太酷了,还有更多选择。这只是最简单的答案。
我的意思是,不是让InstancePerDependency
使用文字端口号,而是使用函数来获取端口号。
例如,假设SerialPortController
自动总是具有最新值。如果您向ISettingsModel
求单身ISettingsModel
,则它总是 。您可以更改控制器以改为使用ConveyorSerialPort
。
ISettingsModel
在这种情况下,由public class SerialPortController
{
private readonly ISettingsModel _model;
public SerialPortController(ISettingsModel model)
{
this._model = model;
}
public void DoSomething()
{
// port will always be up to date.
var port = this._model.ConveyorSerialPort;
this.CommunicateOn(port);
}
}
来保持其值是最新的,但是只要发生这种情况,控制器就可以是单例(理想情况下ISettingsModel
也可以是单例) '会有一个captive dependency situation。
但是,假设ISettingsModel
每次解决都生成。为了获得新的设置,您必须获得一个新的ISettingsModel
。没关系,您也可以使用ISettingsModel
使用Autofac:
Func<T>
自动生成的public class SerialPortController
{
private readonly Func<ISettingsModel> _modelFactory;
public SerialPortController(Func<ISettingsModel> modelFactory)
{
this._modelFactory = modelFactory;
}
public void DoSomething()
{
// port will always be up to date.
var port = this._modelFactory().ConveyorSerialPort;
this.CommunicateOn(port);
}
}
将从容器中复制一个全新的Func<ISettingsModel>
。由于您的控制器是单例,因此它将来自容器的根。 请注意ISettingsModel
是一次性的。如果是一次性的(ISettingsModel
),则Autofac会坚持使用直到容器被丢弃,从而导致内存泄漏。 There are ways to work around this, too.,但可能会变得有点复杂,我想为您提供一个有用的答案。该文档非常好(如果我自己也这么说的话),并且有很多示例。它很长,但是值得花时间检查一下。