如何通过 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 容器为静态属性创建类的对象

你可以像这样用 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.StaticObjectPerson类的实例,而不是类型。类型参数需要类型。如果您想使用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 类的可能性。

话虽如此,这里有多种代码异味,我更愿意找到另一个选项(一般来说,静态字段的使用是一个错误)。