tags:

views:

69

answers:

2

I'm attempting to create a WPF custom control that includes a reference to the unity container that has been created in the BootStrapper - e.g.

The reason being that I would like the custom control to be able to resolve the unity container to be able to use some of the services that have been registered to the container. e.g. a user preference service / an entitlements service.

So far I have created my custom control and have included in the code behind file the following dependency property

public static readonly DependencyProperty ContainerProperty = DependencyProperty.Register("Container", typeof(UnityContainer), typeof(SomeCustomWPFControl), new PropertyMetadata("DefaultTestValue"));

    public UnityContainer Container
    {
        get { return (UnityContainer)GetValue(ContainerProperty); }
        set { SetValue(ContainerProperty, value); }
    }

In the WPF form where I'm attempting to include my custom control, I've added the following line to the Resources area:

<Unity:UnityContainer x:Key="unitContainer"></Unity:UnityContainer>

In the form it's self I've attempted to create the custom control:

<Globe:SomeCustomWPFControl Container="{DynamicResource unitContainer}" DockPanel.Dock="Right" x:Name="JimEditor1" Grid.Column="0" Grid.Row="3"></Globe:SomeCustomWPFControl>

The only error information I receive at run time is

Error at object 'System.Windows.Controls.Grid' in markup file '[assembly name];[path/file].xaml' Line 135 Position 22.

Any suggestions as to where I'm going wrong? Thx.

Full Xaml:

<UserControl x:Class="DB.GPF.Globe.Views.JimTestPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:Globe="clr-namespace:DB.GPF.Globe" 
xmlns:Unity="clr-namespace:Microsoft.Practices.Unity;assembly=Microsoft.Practices.Unity">
<UserControl.Resources>
    <Unity:UnityContainer x:Key="unitContainer"></Unity:UnityContainer>
</UserControl.Resources>
<Grid>
    <Globe:SomeCustomWPFControl Container="{DynamicResource unitContainer}" x:Name="JImTestControl1"></Globe:SomeCustomWPFControl>
</Grid>

Update: The problem appears to be having a DependencyProperty of type UnityContainer or IUnityContainer, if the type is changed to an inbuilt .Net type, e.g. string then it runs fine. Any ideas why we can't have a DependencyProperty of type UnityContainer or IUnityContainer?

A: 
<Globe:SomeCustomWPFControlContainer="{DynamicResource unitContainer}" DockPanel.Dock="Right" x:Name="JimEditor1" Grid.Column="0" Grid.Row="3"></Globe:SomeCustomWPFControlContainer>

There is a problem in you xaml right after <Globe:SomeCustomWPFControlContainer. You're missing a property to bind to.

EDIT: your get value is also wrong. You have GetValue(GetValue(ContextMenuProperty)) and it should be ...

public UnityContainer Container
{
    get { return (UnityContainer)GetValue(ContainerProperty); }
    set { SetValue(ContainerProperty, value); }
}
RonaldV
Sorry, copy and paste error! Here's the code formatted correctly:
Jim
<Globe:SomeCustomWPFControl Container="{DynamicResource unitContainer}" DockPanel.Dock="Right" x:Name="JimEditor1" Grid.Column="0" Grid.Row="3"></Globe:SomeCustomWPFControl>
Jim
Thanks for the quick responses, you are of course correct, I've changed this in my code, but it's had no effect as I'm presuming it fails before the getter is used. I'm presuming the error is down to the run time not being able to find my unity controller, but can't figure out how to include this correctly in the resource area.
Jim
+1  A: 

I think , embedding Unity in Custom Control is not a good idea.

If you need to change some properties of your custome control than expose those properties and change them

saurabh
The idea is that during the control creation, it will use the services to get hold of the preferences and entitlements that apply to that control. I.e. if it shows date in UK/US format, if the current user can adit that control. etc...
Jim
Can't you change these properties without embedding unity in your code? Why i am saying this becoz if yoy embedd unity in your control , your control itself depend upon the unity and if in future , you need to replace unity with someother DI provider than you will change your Custom Control which i think is not a good advice, rest it's your code , you can do what you want to do in it :)
saurabh
saurabh is right. You shouldn't add a container to your code. I would always recommend against it. The container should inject the objects and values into your control.
RonaldV
Thanks for your responses guys but I don't understand your objections to this at the moment. The idea of using unity is to allow for the changing of the service implementations I'm making use of in the future in true IoC style.
Jim
@Jim I believe the objections arise from the fact that you're replacing a dependency on a given service implementation with a dependency on the container itself. Better practice would be to have your custom control accept an `IPreferenceServer`, for example, and use the Unity container *outside the control* to resolve an `IPreferenceServer` implementation **and then inject the service into the control.**
djacobson
Avatar
@djacobson, that is precisely what I'm trying to achieve! :o) however as I'm using unity to create the view and the view is creating the control (using the xaml) how can I get unity to populate the IPreferenceServer param on the controls constructor?
Jim