Caliburn-Micro / Caliburn.Micro

A small, yet powerful framework, designed for building applications across all XAML platforms. Its strong support for MV* patterns will enable you to build your solution quickly, without the need to sacrifice code quality or testability.
http://caliburnmicro.com/
MIT License
2.8k stars 778 forks source link

[propose Help Wanted] Correct way to create an instance that "persists"? #711

Closed zlittell closed 4 years ago

zlittell commented 4 years ago

I am not really a high level object oriented programmer, so I have been struggling through an app. It has been fun to learn though, and it has been a lot of learning.

I am at a point where I want to create a helper class that would always exist, this would capture events from the aggregator and parse them into a model.

My problem is that I registered the instance and it just never instantiates it. I can put a breakpoint in the constructor of the helper and it never breaks. If I register the helper as a singleton and then pass it in the constructor of my main view model it works fine because it seems something is requesting it from the container and then the container creates it finally. I thought registering instances provided this functionality over singletons, but I must be mistaken. Is this the correct way to handle this or is there some better way? My main view model never touches the helper, it is just supposed to sit in the background and catch events, so passing it in the constructor seems silly.

-Zack-

zlittell commented 4 years ago

More info:

When I initially made this I was using an instance registration command that looked like this: this.container.RegisterInstance(typeof(DeviceHelper), typeof(DeviceHelper).ToString(), typeof(DeviceHelper)); Which is definitely why it wasn't breaking in the constructor.

I have now switched to trying to do this this.container.RegisterInstance(typeof(DeviceHelper), typeof(DeviceHelper).ToString(), new DeviceHelper());

But my problem is that I inject dependencies into the constructor of DeviceHelper. It complains that I am not providing the parameters required. public DeviceHelper(IEventAggregator aggregator, DeviceModel model)

EDIT: This is how I got it to work this.container.RegisterInstance(typeof(DeviceHelper), typeof(DeviceHelper).ToString(), new DeviceHelper(this.container.GetInstance<IEventAggregator>(), this.container.GetInstance<Models.DeviceModel>())); I have seen this mentioned as "Antipattern" but normally refers to manually getting instances in other code not the bootstrapper config. My final question, is this the best way to do this or is there something more preferred?

nigel-sampson commented 4 years ago

Sounds like you want to use Singleton.

zlittell commented 4 years ago

I can see how a singleton would work better because I only ever want one, but the singleton isn't created until called. What would be the preferred method of causing the singleton instance to be created in the bootstrapper so that it runs in the background of the app constantly.

nigel-sampson commented 4 years ago

I would probably just resolve the singleton from the container at startup to ensure its creation.

zlittell commented 4 years ago

So I set this up when I got home. Just added a section to the configure function that calls this.container.GetInstance() and another one that I wouldn't mind having the app setup right away and not rely on the viewmodel to request it.

Feel dumb after I have it all working, but thank you for all the explanations.