Using prism 5.0 to develop a wpf add-on - c#

My app is an IDE add-on, so the project is a wpf user control. I want to use Prism to refector it now. When I debug the app, it threw such an exception in InitializeComponent(); of the MainView's constructor:
"ServiceLocationProvider must be set."
I also found a similar thread here: Strange exception in Prism application
but there's no solution.
This is my bootstrapper class:
class Bootstrapper : UnityBootstrapper
{
protected override System.Windows.DependencyObject CreateShell()
{
return ServiceLocator.Current.GetInstance<MainView>();
}
protected override void ConfigureModuleCatalog()
{
base.ConfigureModuleCatalog();
ModuleCatalog catalog = (ModuleCatalog)this.ModuleCatalog;
catalog.AddModule(typeof(ModuleInit));
}
}
This is my ModuleInit class:
public class ModuleInit : IModule
{
IRegionManager regionManager;
IUnityContainer container;
public ModuleInit(IUnityContainer container, IRegionManager regionManager)
{
this.container = container;
this.regionManager = regionManager;
}
public void Initialize()
{
this.container.RegisterType<ViewModelA>(new ContainerControlledLifetimeManager());
this.container.RegisterType<MainViewModel>(new ContainerControlledLifetimeManager());
this.regionManager.RegisterViewWithRegion(Models.RegionNames.ARegion, () => this.container.Resolve<ViewModelA>());
}
}
Because this is a user control project, so there's no App.xaml and App.xaml.cs file. I can bootstrapper's Run method in MainView's constructor:
public MainView()
{
InitializeComponent();
Bootstrapper strapper = new Bootstrapper();
strapper.Run();
}
But the exception is thrown in the first line of the constructor. Anyone can help?
Furthermore, is there a way to use Region without modularity? My app only contains one project, it needn't modularity. If yes, where can I register the views, services and viewmodels?

Somewhere, for example in your bootstrapper before init code, you have to define your IoC container.
This is how it's done in ViewModelLocator by default:
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

Related

Multiple navigation control through dependency injection

My base content class. I used this class as a theme for my project. I do not know this info relevant or not. In here I create an abstract method that would overload the navigation method.
public abstract class BaseContentPage : ContentPage
{
public readonly BaseViewModel BaseViewModel;
public BaseContentPage(BaseViewModel baseViewModel)
{
BaseViewModel = baseViewModel;
}
public abstract void Navigate(SelectedItemChangedEventArgs e);
}
In my locator where I build the dependency Injection public class Locator. in this class mainly focus on adding this class to the container to make the all code loss coupling
private readonly ContainerBuilder _builder;
public Locator()
{
_builder = new ContainerBuilder();
RegisterTypes();
Container = _builder.Build();
}
public IContainer Container { get; set; }
private void RegisterTypes()
{
_builder.RegisterType<WardListService>().As<IWardListService>();
_builder.RegisterType<WardListPageViewModel>();
_builder.RegisterType<WardListPage>();
_builder.RegisterType<PatientService>().As<IPatientService>();
_builder.RegisterType<PatientListPageViewModel>();
_builder.RegisterType<PatientListViewPage>();
_builder.RegisterType<PatientDetailsPageViewModel>();
_builder.RegisterType<PatientDetailsViewPage>(); }
In my app.Xaml.Cs file
public App()
{
InitializeComponent();
Locator locator = new Locator();
Container = locator.Container;
MainPage = new NavigationPage(Container.Resolve<WardListPage>());
}
public static IContainer Container;
I used this method for navigation in my view code behind page
public async override void Navigate(SelectedItemChangedEventArgs e)
{
PatientDetailsViewPage patientDetailsViewPage = App.Container.Resolve<PatientDetailsViewPage>();
patientDetailsViewPage.BaseViewModel.SelectedPatient = e.SelectedItem as PatientViewModel;
await Navigation.PushAsync(patientDetailsViewPage);
}
This code is working perfectly but this only can navigate to one page.meaning as an example on one page we have two buttons that navigate to two different pages. I don't know how to implement this task using above navigate overloader. How to do it can anyone give suggestion to overcome the problem?. Also, I used autofac for dependency injection Thank you
You can define container in your CustomNavigationPage and use in every navigation page instance.
public class CustomNavigationPage : NavigationPage
{
public static IContainer Container;
public CustomNavigationPage()
{
Locator locator = new Locator();
locator.RegisterTypes();
Container = locator.Container();
}
}
It is dummy code what i mentioned.
You creating a navigation page that customized. So you can use this navigating your pages for example:
CustomNavigationPage.PushASync(new TestPage(Container.Resolve<WardListPage>())):
If use this your custom navigation page will be resolve your dependencies every call.
To improve performance you can register your dependencies with
singleton pattern. When the app started, dependencies will be registered.
After you use this registered dependencies.
There is an improvement : You define a static locator with singleton pattern it registers dependencies in app.cs
public sealed class Locator
{
private static Locator locator = null;
private static readonly object padlock = new object();
Locator()
{
//your registries
}
public static Locator Locator
{
get
{
lock (padlock)
{
if (locator == null)
{
locator = new Locator();
}
return locator;
}
}
}
}
And your app.cs :
public App()
{
InitializeComponent();
Locator locator = new Locator();
Container = locator.Container;
.
.
}
public static IContainer Container;
This way you only one time register your dependencies. There is no duplication of code. Only one instance will be used.

navigation and how to register the view with the region?

I have two views between which I want to navigate on button click and they are registered with a region on module initialization like this:
public class ModuleTaxCalc : IModule //PRISM MODULE POWER
{
IUnityContainer container;
IRegionManager regionManager;
public ModuleTaxCalc(IUnityContainer container, IRegionManager regionManager)
{
this.container = container;
this.regionManager = regionManager;
}
public void Initialize()
{
container.RegisterType<ICustomer, Customer>();
//container.RegisterType<object, ViewA>("ViewA");
//container.RegisterType<object, ViewB>("ViewB");
regionManager.RegisterViewWithRegion("TaxCalculatorRegion", typeof(ViewA));
regionManager.RegisterViewWithRegion("TaxCalculatorRegion", typeof(ViewB));
}
}
My issue is that the 'ViewA' gets visible automatically when application starts/
if I do this instead:
public void Initialize()
{
container.RegisterType<object, ViewA>("ViewA");
container.RegisterType<object, ViewB>("ViewB");
}
then both views are invisible and become visible only on button click, but I guess they are not registered with the region in this case.
For navigation, you want to register the views for navigation and then navigate to them.
// register the view
container.RegisterTypeForNavigation<ViewA>();
// and some time later, show it in the region
regionManager.RequestNavigate( "TaxCalculatorRegion", "ViewA" );
If you register the view with a region instead, it will be automatically displayed in that region (View Discovery). Much more detailed info is available in the Prism documentation...

How to get the same instance of object from Unity container in various modules of Prism application?

I have a Prism application where I have three modules:
SharedServiceModule(I am using SharedServices to communicate between modules)
ModuleA
ModuleB
SharedServiceModule just has interface and its implementation CommonService:
public interface ICommonService
{
string SomeStorage { get; set; }
}
public class CommonService : ICommonService
{
string fooStorage;
public string FooStorage
{
get
{
return fooStorage;
}
set
{
fooStorage = value;
OnPropertyChanged("FooStorage");
}
}
}
What I want is to create communication between modules using Shared Services. So I assign «ModuleAValue» at ViewModelA of ModuleA and then I want to read this value in ViewModelB of ModuleB. Let's see details.
I create a single instance of ICommonService in ViewModelA of ModuleA and assign a value "ModuleAValue" to FooStorage:
Method of ViewModelA:
unityContainer = new UnityContainer();
unityContainer.RegisterType<ICommonService, CommonService>(new ContainerControlledLifetimeManager());
IMyService someFoo = unityContainer.Resolve<ICommonService>();
someFoo.FooStorage = "ModuleAValue";//value is "ModuleAValue" in FooStorage
Then I want to read this data in viewModelB of ModuleB. But value of FooStorage is not 'Module A', but just empty value:
Method of ViewModelB:
IUnityContainer unityContainer=new UnityContainer//creation of UnityContainer in ModuleB
ICommonService someFoo = unityContainer.Resolve<CommonService>();
string str=someFoo.FooStorage;//value is empty in
FooStorage, but it should be "ModuleAValue"
My Bootstrapper is:
public class Bootstrapper:UnityBootstrapper
{
protected override DependencyObject CreateShell()
{
return Container.Resolve<Shell>();
}
protected override void InitializeShell()
{
base.InitializeShell();
App.Current.MainWindow = (Window)Shell;
App.Current.MainWindow.Show();
}
protected override void ConfigureContainer()
{
base.ConfigureContainer();
Container.RegisterType<IShellViewModel, ShellViewModel>();
RegisterTypeIfMissing(typeof(IMyService), typeof(MyService), true);
}
protected override RegionAdapterMappings ConfigureRegionAdapterMappings()
{
RegionAdapterMappings mappings = base.ConfigureRegionAdapterMappings();
mappings.RegisterMapping(typeof(StackPanel), Container.Resolve<StackPanelRegionAdapter>());
return mappings;
}
protected override IModuleCatalog CreateModuleCatalog()
{
ModuleCatalog catalog = new ModuleCatalog();
catalog.AddModule(typeof(ModuleAModule));
catalog.AddModule(typeof(ModuleBModule));
return catalog;
}
}
What am I doing wrong? In my view, Unity always creates new instance of CommonService. What am I doing wrong while taking the same instance from Unity container?
Any help will be greatly appreciated!
Your app's bootstrapper creates an UnityContainer for you, see UnityBootstrapper.cs:
protected virtual IUnityContainer CreateContainer()
{
return new UnityContainer();
}
The bootstrapper should also register the container as viewmodel factory:
protected override void ConfigureContainer()
{
base.ConfigureContainer();
ViewModelLocationProvider.SetDefaultViewModelFactory( type => Container.Resolve( type ) );
}
In your module definition class, you can have this 'global' container injected as dependency:
public class ClientModule : IModule
{
private readonly IUnityContainer _unityContainer;
public ClientModule( IUnityContainer unityContainer )
{
_unityContainer = unityContainer;
}
}
In your module's initialization, you register types or instances with this container:
public void Initialize()
{
// Register services
_unityContainer.RegisterType<IGameClock, LocalGameClock>( new ContainerControlledLifetimeManager() );
_unityContainer.RegisterType<IWorldStateService, LocalWorldStateService>( new ContainerControlledLifetimeManager() );
}
In your views (in the xaml), you can now use ViewModelLocator.AutoWireViewModel="True" to automatically create viewmodels for your views. The ViewModelLocationProvider will use the 'global' container to resolve the viewmodels (as defined above), so all viewmodels will receive the same instance of our, say, IGameClock.
Ancilliary piece of advice: you don't want to call Resolve directly yourself. Using it this way defeats the whole purpose of using unity in the first place. It's better to have your dependencies injected as constructor parameters, and to only use the container at the highest level, i.e. in module initialization. And you should never need to create more than one container, lest you know exactly what you're doing.
You shouldn't create the new container instance. Usually there should be only one container instance in your application.
If you are using prism your view model should be created from a container also (if prism is responsible for view model creation than it is created from container ). In such case just create the constructor in your view model with parameter of type ICommonService like this:
public ViewModelA(ICommonService service) { ... }
then during creation of the ViewModel the same instance of the service will be injected to that ViewModel.
And usually common services are registered in the Shell during application startup. But if you want you can also register a service in a module, just use the same unity container that was created during application start. In the viewmodel use constructor with parameter of type IUnityContainer.

Re-implementing WindowManager using ModernUI + Caliburn.Micro combination

Here Caliburn.Micro was successfully combined with ModernUI.
But if we want to use multiple windows we also need to re-implement Caliburn's WindowManager to work properly with ModernUI. How can it be done?
UPDATE:
(Additional question about IoC-Container/Dependency Injection)
Ok, as I get it: I used a Constructor Injection here:
public class BuildingsViewModel : Conductor<IScreen>
{
public BuildingsViewModel(IWindowManager _windowManager)
{
windowManager = _windowManager;
}
}
As far as BuildingsViewModel resolved from IoC container,
container itself injected ModernWindowManager implementation of IWindowManager interface because of this line in Bootstrapper's Configure() method:
container.Singleton<IWindowManager, ModernWindowManager>();
If I resolving an object instance from container, it injects all needed dependencies. Like a tree.
1) So now I wonder how can I replace this line using an injection(with interface)?
_windowManager.ShowWindow(new PopupViewModel());
2) If I want my whole project match DI pattern, all objects instances must be injected into ModernWindowViewModel, that resolves from container first?
3) Is it okay to use Caliburn's SimpleContainer for whole project, or better use mature framework like Castle Windsor? Should I avoid mixing?
UPDATE2:
4) Integrating an IoC container into an existing application requires creating this container first(in Main() method of console app for example), and then all object instanses must grow from it with injected dependencies?
Simply create your own derived WindowManager and override EnsureWindow:
public class ModernWindowManager : WindowManager
{
protected override Window EnsureWindow(object rootModel, object view, bool isDialog)
{
var window = view as ModernWindow;
if (window == null)
{
window = new ModernWindow();
window.SetValue(View.IsGeneratedProperty, true);
}
return window;
}
}
Any views that you want to use as popups must be based on ModernWindow and must either use a LinkGroupCollection or you must set the ContentSource property of the window, otherwise there will be no content.
You could possibly make this View-First but it works ViewModel-First using the method above.
e.g. to popup my PopupView I did the following
PopupView.xaml
<mui:ModernWindow x:Class="TestModernUI.ViewModels.PopupView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mui="http://firstfloorsoftware.com/ModernUI"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300" ContentSource="/ViewModels/ChildView.xaml">
</mui:ModernWindow>
PopupViewModel.cs
public class PopupViewModel : Screen
{
// Blah
}
Code to popup the view from another ViewModel:
public void SomeMethod()
{
_windowManager.ShowWindow(new PopupViewModel()); // Or use injection etc
}
Don't forget to register ModernWindowManager in place of WindowManager in your container!
e.g. using CM's SimpleContainer
container.Singleton<IWindowManager, ModernWindowManager>();
Obviously the only downside I can see to the above is that you can't seem to put content directly in a ModernWindow, so you have to have two UserControls for every popup!
A workaround would be to change EnsureWindow in ModernWindowManager so that it created a UserControl based on ModernWindow and set the ContentSource to the URI of the view you want to load, this will trigger the content loader and wire up your ViewModel. I'll update if I get a minute to try it.
Update:
Ok, so at the moment it's very hacky, but this could be a starting point for something useful. Basically I'm generating a URI based on the namespace and name of the view.
I'm sure there is a more reliable way of doing this, but for my test project it works:
protected override Window EnsureWindow(object rootModel, object view, bool isDialog)
{
var window = view as ModernWindow;
if (window == null)
{
window = new ModernWindow();
// Get the namespace of the view control
var t = view.GetType();
var ns = t.Namespace;
// Subtract the project namespace from the start of the full namespace
ns = ns.Remove(0, 12);
// Replace the dots with slashes and add the view name and .xaml
ns = ns.Replace(".", "/") + "/" + t.Name + ".xaml";
// Set the content source to the Uri you've made
window.ContentSource = new Uri(ns, UriKind.Relative);
window.SetValue(View.IsGeneratedProperty, true);
}
return window;
}
My full namespace for my view was TestModernUI.ViewModels.PopupView and the URI generated was /ViewModels/PopupView.xaml which then was loaded and bound via the content loader automagically.
Update 2
FYI here is my Bootstrapper configure method:
protected override void Configure()
{
container = new SimpleContainer();
container.Singleton<IWindowManager, ModernWindowManager>();
container.Singleton<IEventAggregator, EventAggregator>();
container.PerRequest<ChildViewModel>();
container.PerRequest<ModernWindowViewModel>();
container.PerRequest<IShell, ModernWindowViewModel>();
}
Here I create the container, and register some types.
The CM services such as WindowManager and EventAggregator are both registered against their respective interfaces and as singletons so only 1 instance of each will be available at run time.
The view models are registered as PerRequest which creates a new instance every time you request one from the container - this way you can have the same window popup multiple times without strange behaviour!
These dependencies are injected into the constructor of any objects resolved at run time.
Update 3
In answer to your IoC questions:
1) So now I wonder how can I replace this line using an injection(with interface)? _windowManager.ShowWindow(new PopupViewModel());
Since your viewmodels will now usually need dependencies you need to have some way of injecting them into the instances. If PopupViewModel had several dependencies, you could inject them into the parent class but this would couple the parent viewmodel to PopupViewModel in some way.
There are a couple of other methods you can use to get an instance of PopupViewModel.
Inject it!
If you register PopupViewModel as PerRequest you will get a new instance of it every time you request it. If you only need one popup instance in your viewmodel you can just inject it:
public class MyViewModel
{
private PopupViewModel _popup;
private IWindowManager _windowManager;
public MyViewModel(PopupViewModel popup, IWindowManager windowManager)
{
_popup = popup;
_windowManager = windowManager;
}
public void ShowPopup()
{
_windowManager.ShowPopup(_popup);
}
}
The only downside is that the instance will be the same one if you need to use it multiple times in the same viewmodel, though you could inject multiple instances of PopupViewModel if you knew how many you needed at the same time
Use some form of on-demand injection
For dependencies which are required later on you can use on-demand injection such as a factory
I don't think Caliburn or SimpleContainer support factories out of the box, so the alternative is to use IoC.Get<T>. IoC is a static class which lets you access your DI container after instantiation
public void ShowPopup()
{
var popup = IoC.Get<PopupViewModel>();
_windowManager.ShowWindow(popup);
}
You need to make sure you have correctly registered the container in your bootstrapper and delegated any calls to CM's IoC methods to the container - IoC.Get<T> calls the bootstrapper's GetInstance and other methods:
Here's an example:
public class AppBootstrapper : BootstrapperBase {
SimpleContainer container;
public AppBootstrapper() {
Initialize();
}
protected override void Configure() {
container = new SimpleContainer();
container.Singleton<IWindowManager, ModernWindowManager>();
container.Singleton<IEventAggregator, EventAggregator>();
container.PerRequest<IShell, ModernWindowViewModel>();
// Register viewmodels etc here....
}
// IoC.Get<T> or IoC.GetInstance(Type type, string key) ....
protected override object GetInstance(Type service, string key) {
var instance = container.GetInstance(service, key);
if (instance != null)
return instance;
throw new InvalidOperationException("Could not locate any instances.");
}
// IoC.GetAll<T> or IoC.GetAllInstances(Type type) ....
protected override IEnumerable<object> GetAllInstances(Type service) {
return container.GetAllInstances(service);
}
// IoC.BuildUp(object obj) ....
protected override void BuildUp(object instance) {
container.BuildUp(instance);
}
protected override void OnStartup(object sender, System.Windows.StartupEventArgs e) {
DisplayRootViewFor<IShell>();
}
Castle.Windsor supports factories so that you can Resolve and Release your components and manage their lifetime more explicitly, but I won't go into that here
2) If I want my whole project match DI pattern, all objects instances must be injected into ModernWindowViewModel, that resolves from container first?
You only need to inject the dependencies that the ModernWindowViewModel needs. Anything that is required by children is automatically resolved and injected e.g.:
public class ParentViewModel
{
private ChildViewModel _child;
public ParentViewModel(ChildViewModel child)
{
_child = child;
}
}
public class ChildViewModel
{
private IWindowManager _windowManager;
private IEventAggregator _eventAggregator;
public ChildViewModel(IWindowManager windowManager, IEventAggregator eventAggregator)
{
_windowManager = windowManager;
_eventAggregator = eventAggregator;
}
}
In the above situation, if you resolve ParentViewModel from the container - the ChildViewModel will get all it's dependencies. You don't need to inject them into the parent.
3) Is it okay to use Caliburn's SimpleContainer for whole project, or better use mature framework like Castle Windsor? Should I avoid mixing?
You can mix, but it might be confusing as they won't work with each other (one container won't know about the other). Just stick with one container, and SimpleContainer is fine - Castle Windsor has a lot more features, but you might never need them (I've only used a few of the advanced features)
4) Integrating an IoC container into an existing application requires creating this container first(in Main() method of console app for example), and then all object instanses must grow from it with injected dependencies?
Yes, you create the container, then you resolve the root component (in 99.9% of applications there is one main component which is called the composition root), and this then builds the full tree.
Here is an example of a bootstrapper for a service based application. I'm using Castle Windsor and I wanted to be able to host the engine in a Windows service or in a WPF application or even in a Console Window (for testing/debug):
// The bootstrapper sets up the container/engine etc
public class Bootstrapper
{
// Castle Windsor Container
private readonly IWindsorContainer _container;
// Service for writing to logs
private readonly ILogService _logService;
// Bootstrap the service
public Bootstrapper()
{
_container = new WindsorContainer();
// Some Castle Windsor features:
// Add a subresolver for collections, we want all queues to be resolved generically
_container.Kernel.Resolver.AddSubResolver(new CollectionResolver(_container.Kernel));
// Add the typed factory facility and wcf facility
_container.AddFacility<TypedFactoryFacility>();
_container.AddFacility<WcfFacility>();
// Winsor uses Installers for registering components
// Install the core dependencies
_container.Install(FromAssembly.This());
// Windsor supports plugins by looking in directories for assemblies which is a nice feature - I use that here:
// Install any plugins from the plugins directory
_container.Install(FromAssembly.InDirectory(new AssemblyFilter("plugins", "*.dll")));
_logService = _container.Resolve<ILogService>();
}
/// <summary>
/// Gets the engine instance after initialisation or returns null if initialisation failed
/// </summary>
/// <returns>The active engine instance</returns>
public IIntegrationEngine GetEngine()
{
try
{
return _container.Resolve<IIntegrationEngine>();
}
catch (Exception ex)
{
_logService.Fatal(new Exception("The engine failed to initialise", ex));
}
return null;
}
// Get an instance of the container (for debugging)
public IWindsorContainer GetContainer()
{
return _container;
}
}
Once the bootstrapper is created, it sets up the container and registers all services and also plugin dlls. The call to GetEngine starts the application by resolving Engine from the container which creates the full dependency tree.
I did this so that it allows me to create a service or a console version of the application like this:
Service Code:
public partial class IntegrationService : ServiceBase
{
private readonly Bootstrapper _bootstrapper;
private IIntegrationEngine _engine;
public IntegrationService()
{
InitializeComponent();
_bootstrapper = new Bootstrapper();
}
protected override void OnStart(string[] args)
{
// Resolve the engine which resolves all dependencies
_engine = _bootstrapper.GetEngine();
if (_engine == null)
Stop();
else
_engine.Start();
}
protected override void OnStop()
{
if (_engine != null)
_engine.Stop();
}
}
Console App:
public class ConsoleAppExample
{
private readonly Bootstrapper _bootstrapper;
private IIntegrationEngine _engine;
public ConsoleAppExample()
{
_bootstrapper = new Bootstrapper();
// Resolve the engine which resolves all dependencies
_engine = _bootstrapper.GetEngine();
_engine.Start();
}
}
Here's part of the implementation of IIntegrationEngine
public class IntegrationEngine : IIntegrationEngine
{
private readonly IScheduler _scheduler;
private readonly ICommsService _commsService;
private readonly IEngineStateService _engineState;
private readonly IEnumerable<IEngineComponent> _components;
private readonly ConfigurationManager _configurationManager;
private readonly ILogService _logService;
public IntegrationEngine(ICommsService commsService, IEngineStateService engineState, IEnumerable<IEngineComponent> components,
ConfigurationManager configurationManager, ILogService logService)
{
_commsService = commsService;
_engineState = engineState;
_components = components;
_configurationManager = configurationManager;
_logService = logService;
// The comms service needs to be running all the time, so start that up
commsService.Start();
}
All of the other components have dependencies, but I don't inject those into the IntegrationEngine - they are handled by the container

Is it possible to use IWindowManager from Micro.Caliburn in Prism UnityContainer

I was looking a WindowManager for UnityContainer and I register in my container this service.
But at the momento when I plan to utilize this service to show a UserControl, it's not possible. It tells that it can't find a view for the view model 'x'.
I'm using Unity as the bootstrapper.
public class Bootstrapper : UnityBootstrapper
{
protected override DependencyObject CreateShell()
{
MainWindow shell = Container.Resolve<MainWindow>();
shell.Show();
return shell;
}
protected override void ConfigureContainer()
{
base.ConfigureContainer();
Container.RegisterInstance<IWindowManager>(new WindowManager());
}
}

Categories