Accesing Shell from Module - II

Jan 2, 2009 at 12:04 AM
I need to modify some Shell properties from a modue, for instance the title.

I created a service in the shell, like

private IShell shell
public UIService(IShell Shell)
{
    shell = Shell;
}

public void SetTitle(sring Title)
{
    Shell _shell = shell as Shell;
    _shell.lblTitle.Content = Title;
}

Then in my Bootstrapper I register my service:

protected override DependencyObject CreateShell()
{
    Container.RegisterType<IShell, Shell>();
    Container.RegisterType<IUIService, UIService>(new ContainerControllerLifetimeManager());
    Container.Resolve<UIService>();
   
    ShellPresenter presenter = Container.Resolve<ShellPresenter>();
    IShell view = presenter.View;
    view.ShowView();
    return view as DependencyObject;
}

Everything works, but I cant use IUIService in the module, I get an error in the module initializer.
Some help, please.

Marcos
Jan 2, 2009 at 12:49 AM
I'd be curious if Resolve<IUIService>(), versus UIService; would eliminate your error...   
   
Container.RegisterType<IUIService, UIService>(new ContainerControllerLifetimeManager());
Container.Resolve<UIService>();
Jan 2, 2009 at 7:33 AM
No, Bill, It's exactly the same.
Jan 2, 2009 at 11:32 AM
Can you share the error? 
Jan 2, 2009 at 12:14 PM
When I try to resolve a class 

     CommonToolbarPresenter commonToolbarPresenter = container.Resolve<CommonToolbarPresenter>();
     IRegion commonToolbarRegion = regionManager.Regions[RegionNames.CommonToolbarRegion];
    commonToolbarRegion.Add(commonToolbarPresenter.view);

that has a variable 
    private IUIService UIService;

and a initializer like

public CommonToolbarPresenter(CommonToolbarView View, IUIService uiService)
{
     view = View;
     UIService = uiService;

}

I get the following error:


Resolution of the dependency failed, type = "W2.Affaires.CommonToolbarPresenter", name = "". Exception message is: The current build operation (build key Build Key[W2.Affaires.CommonToolbarPresenter, null]) failed: The parameter uiService could not be resolved when attempting to call constructor W2.Affaires.CommonToolbarPresenter(W2.Affaires.CommonToolbarView View, W2.Shell.IUIService uiService). (Strategy type BuildPlanStrategy, index 3)
Jan 2, 2009 at 1:35 PM

Nothing obvious jumps out at me.  Perhaps I could persuade you to go a different route?

Demo I scraped together for you resides HERE

ModuleA.cs contains the following:

public void Initialize()

{

    UIEventArgs args = new UIEventArgs {ShellTitle="Hello World"};

    aggregator.GetEvent<UIEvent>().Publish(args);

}

ShellPresenter.cs contains the following:

public class ShellPresenter

{

    public IShell View { get; set; }

 

    public ShellPresenter(IUnityContainer container,

        IShell view, IEventAggregator aggregator)

    {

        View = view;

        View.Model = container.Resolve<IShellPresentationModel>();

        aggregator.GetEvent<UIEvent>().Subscribe(UIEventHandler);

    }

 

    private void UIEventHandler(UIEventArgs e)

    {

        View.Model.ShellTitle = e.ShellTitle;

    }

}

Shell.xaml contains the following:

<Window x:Class="ShellAccess.Shell"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    Title="{Binding ShellTitle}" Height="300" Width="300">

  <Grid>

 

  </Grid>

</Window>

<!--EndFragment-->
<!--EndFragment-->

Jan 2, 2009 at 1:53 PM
It's a good workaround.  Thanks a lot, Bill
Jan 2, 2009 at 2:41 PM
Edited Jan 2, 2009 at 2:42 PM

Hi Marcos,

 

Looking at your code, it seems that you are creating the Shell twice:

1.       When you resolve the UIService class, the Shell is injected in the constructor through the container creating an instance of the Shell.

2.       When you resolve the ShellPresenter, another instance of the Shell is created by the container and injected in the View property of the class.

 

If this is the cause of your error, you could do the following to avoid creating the Shell twice:

·         Register the Shell as a singleton. In this way the container always injects the same instance:

 

// Note: The ConfigureContainer method is the place where you typically write code to register services in the Bootstrapper class.

protected override void ConfigureContainer()

{

Container.RegisterType<IShell, Shell>(new ContainerControlledLifetimeManager());

Container.RegisterType<IUIService, UIService>(new ContainerControlledLifetimeManager());

 

base.ConfigureContainer();

}

 

protected override DependencyObject CreateShell()

{

ShellPresenter presenter = Container.Resolve<ShellPresenter>();

 

IShell view = presenter.View;

view.ShowView();

 

return view as DependencyObject;

}

 

Hope it helps.

 

Mariano Converti

http://blogs.southworks.net/mconverti

 

Jan 2, 2009 at 3:09 PM
Hi Mariano,

I follow your advice but I'm still getting the same error.