0

I am developing WPF application using Prism framework. Let's begin.

I have a simple class Person and I would like to create an object for static field staticObject of property 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; }
    }
}

What I've tried to do, but caught an error "The type name ‘StaticObject’ does not exist in the type ‘Person’", is:

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’"
}

Is it possible to resolve UnityContainer for static property?

Update:

Cause I am using AvalonDock to create dockingable UI, so I cannot avoid using a static property (I've tried to avoid using a static property but I've not found a chance to avoid the static property).

Here a static property "This" which is used everywhere in AvalonDock Test example.

class Workspace : ViewModelBase
{     
  static Workspace _this = new Workspace(regionManager);

  public static Workspace This
  {
      get { return _this; }
  }
}

So this is a stumbling block for me to use UnityContainer. I cannot figure out how can I solve this task.

StepUp
  • 36,391
  • 15
  • 88
  • 148

3 Answers3

1

You can register instances with unity like this

var theImplementation = new MyClass();
_unityContainer.RegisterInstance<IWhatEver>( theImplementation );

That being said, you should skip the whole static property stuff and simply register the Person type with a ContainerControlledLifetimeManager. This way, you always get the same instance, exactly like your static property, but more test friendly...

// 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
    }
}
Haukinger
  • 10,420
  • 2
  • 15
  • 28
  • cause I am using AvalonDock to create dockingable UI. And there is a static property "This" which is used everywhere in Test example. https://avalondock.codeplex.com – StepUp Jan 19 '16 at 13:23
  • `Workspace.This` is used to access the `Workspace`singleton. That's exactly the usecase for the `ContainerControlledLifetimeManager`: register the `Workspace` type with this lifetime, then add it as dependency to all the types that use it, i.e. `FileViewModel`, `FileStatsViewModel` and `MainWindow` and as a last step replace all usages of `Workspace.This` therein with a reference to the dependency. Btw, `Workspace` should rather be named `MainWindowViewModel` here. – Haukinger Jan 19 '16 at 15:02
  • **then add it as dependency to all the types that use it** - you mean that I should send `IUnityContainer unityContainer` through the parameter of constructor of classes such as `FileViewModel`, `FileStatsViewModel` and `MainWindow`? – StepUp Jan 19 '16 at 15:09
  • I mean "give those types a constructor parameter of type `Workspace`, so that your unity container will inject the dependency upon resolving the type". Don't send the container, tell the container what to send. If `ViewAViewModel`'s constructor had a parameter like that in the prism sample (https://github.com/PrismLibrary/Prism-Samples-Wpf/tree/master/HelloWorld), the container would fill that in... – Haukinger Jan 19 '16 at 17:31
0

Person.StaticObject is an instance of Person class, not a type. Type parameters require a type. If you'd like to use the type of StaticObject as the type parameter to RegisterType, I believe it is unfortunately not possible without reflection. I don't have experience with reflection, but maybe someone else will give you a concrete answer to your problem.

Kapol
  • 6,383
  • 3
  • 21
  • 46
  • my goal is just create an object for `staticObject` field using `Unity`. It will be really cool if someone advice to me how can I instantiate static property – StepUp Jan 19 '16 at 11:12
0

A really simple solution could be:

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; }
    }
}

You will have to deal somehow the possibility of accessing the Person class before having any Person instance.

Having said that there are multiple code smells here and I would prefer to find another option (generally speaking the usage of static fields is an error).

Ignacio Soler Garcia
  • 21,122
  • 31
  • 128
  • 207