如何通过 Unity 容器为静态属性创建类的对象
本文关键字:创建 属性 对象 静态 何通过 Unity | 更新日期: 2023-09-27 18:31:01
我正在使用Prism框架开发WPF应用程序。让我们开始吧。
我有一个简单的类Person
,我想为属性StaticObject
的静态字段staticObject
创建一个对象。
public class Person
{
IUnityContainer unityContainer;
public Person(IUnityContainer _unityContainer)
{
unityContainer=_unityContainer;
}
private static Person staticObject = unityContainer.Resolve<Person>;//here
//unityContainer is always NULL as constructor is called AFTER this statement
public static Person StaticObject
{
get { return staticObject; }
set { staticObject = value; }
}
}
我尝试做的,但发现错误"类型名称'StaticObject'在类型'人'中不存在",是:
public class MyModule : ModuleBase
{
Container.RegisterType<Person.StaticObject>(new ContainerControlledLifetimeManager());
//The line above it is not working.
//Error is "The type name ‘StaticObject’ does not exist in the type ‘Person’"
}
是否可以解析静态属性的 UnityContainer?
更新:
因为我正在使用 AvalonDock 来创建可停靠的 UI,所以我无法避免使用静态属性(我试图避免使用静态属性,但我没有找到避免静态属性的机会)。
这里有一个静态属性"This",在 AvalonDock 测试示例中随处使用。
class Workspace : ViewModelBase
{
static Workspace _this = new Workspace(regionManager);
public static Workspace This
{
get { return _this; }
}
}
因此,这是我使用UnityContainer的绊脚石。我不知道如何解决这项任务。
你可以像这样用 Unity 注册实例
var theImplementation = new MyClass();
_unityContainer.RegisterInstance<IWhatEver>( theImplementation );
话虽如此,您应该跳过整个静态属性的内容,只需使用 ContainerControlledLifetimeManager
注册Person
类型。这样,您始终可以获得相同的实例,与您的静态属性完全相同,但对测试更友好......
// registration, probably in bootstrapper or module initializer
_unityContainer.RegisterType<Person>( new ContainerControlledLifetimeManager() )
// usage
class PersonConsumer
{
public PersonConsumer( Person theStaticPerson )
{
// theStaticPerson is always the same instance
// you can use it now or store it in a private field for later
}
}
Person.StaticObject
是Person
类的实例,而不是类型。类型参数需要类型。如果您想使用StaticObject
类型作为类型参数来RegisterType
,我相信不幸的是,没有反射是不可能的。我没有反思的经验,但也许其他人会给你一个具体的答案。
一个非常简单的解决方案可能是:
public class Person
{
IUnityContainer unityContainer;
public Person(IUnityContainer _unityContainer)
{
unityContainer=_unityContainer;
staticObject = unityContainer.Resolve<Person>();
}
private static Person staticObject;
public static Person StaticObject
{
get { return staticObject; }
set { staticObject = value; }
}
}
在拥有任何 Person 实例之前,您必须以某种方式处理访问 Person 类的可能性。
话虽如此,这里有多种代码异味,我更愿意找到另一个选项(一般来说,静态字段的使用是一个错误)。