【发布时间】:2013-04-08 00:39:49
【问题描述】:
我正在开发 WPF 应用程序。
我使用StructureMap 来注入依赖项。
存在一些服务层类,它们从构造函数中提供参数。
我传递给构造函数的值将改变运行时间。
表示层的类使用服务为用户呈现数据。每当价值发生变化时,我都会再次注入新价值的服务。但是表示层的活动实例返回先前的值。
我准备了简单的示例以便更好地理解。
// static class that keeps some value
public class ValueKeeper
{
public static string Value { get; set; }
}
public interface IService
{
string Value { get; set; }
}
// Service layer class
public class Service : IService
{
// default constructor
public Service(string value)
{
Value = value;
}
#region IService Members
public string Value { get; set; }
#endregion
}
public class Program
{
private readonly IService _service;
//injecting service class
public Program(IService service)
{
_service = service;
}
// structuremap configuration
private static void Config()
{
ObjectFactory.Initialize(x => x.Scan(scanner =>
{
scanner.TheCallingAssembly();
scanner.WithDefaultConventions();
x.For<IService>().CacheBy(InstanceScope.Hybrid).Use(() =>
{
var service = new Service("value1");
return service;
});
}));
}
// structuremap configuration after value changed.
private static void ReConfig()
{
ObjectFactory.Configure(x => x.Scan(scanner =>
{
x.For<IService>().CacheBy(InstanceScope.Hybrid).Use(() =>
{
var service =new Service(ValueKeeper.Value);
return service;
});
}));
}
private string PresentationMethod()
{
return _service.Value;
}
private static void Main(string[] args)
{
Config(); // Firtst time injecting dependencies
var prog = ObjectFactory.GetInstance<Program>();
Console.WriteLine(prog.PresentationMethod()); // returns "value1"
ValueKeeper.Value = "value 2"; //changing static property
ReConfig(); // reconfig service class with new property
Console.WriteLine(prog.PresentationMethod()); // it returns value1 but I expect value2 .
Console.ReadKey();
}
}
真正的应用程序包含许多表示和服务类。
如何使用新对象和值更改实时服务实例?
更新:
我看到了this 链接。似乎通过使用 Setter Injection 可以更改现有对象。
二传手注射是我的解决方案吗?
【问题讨论】:
-
你能不能不让这个注入的值也成为接口的一个属性,这样你就不必每次都注入一个类的新实例?如果每次只更改构造函数参数,重新注入依赖项似乎是一种可怕的做法。
-
@SimonWhitehead 我不能。因为我示例的服务类实际上是 .NET 库中的一个类。 (数据库上下文)。我必须将连接字符串传递给它的构造函数。
-
@shaahin 没有 IoC 跟踪它创建的实例(除非它的单例)AFAIK。因此,简短的回答是容器无法做到这一点。您可以做的是将 GetInstance() 方法包装在您控制的方法中并跟踪您自己创建的实例,以便您可以在需要时更改它们的依赖关系。但是,我建议您不要这样做,因为在整个应用程序中跟踪实例并非易事。你应该重新考虑你的理由并重新考虑解决方案。
-
@tucaz 谢谢。使用'Setter Injection'怎么样?看来我需要一个解决方案来改变初始化对象的依赖关系。
-
Setter 注入只是将依赖项传递给对象的另一种方式。您正在使用构造函数注入,其中依赖项通过构造函数进行。在 Setter 注入中,它们是通过调用属性中的 set 方法来注入的。那不是你需要的。注入方法是什么无关紧要,IoC 容器不会为您跟踪和更改现有实例。
标签: c# dependency-injection structuremap