I have an instance of IValueConverter in a Silverlight 5 project, which converts custom data into different colors. I need to read the actual color values from a database (as these can be edited by the user).
Since Silverlight uses asynchronous calls to load the data through Entity Framework from the database, I created a simple repository, which holds the values from the db.
The interface:
public interface IConfigurationsRepository
{
    string this[string key] { get; }
}
The implementation:
public class ConfigurationRepository : IConfigurationsRepository
{
    private readonly TdTerminalService _service = new TdTerminalService();
    public ConfigurationRepository()
    {
        ConfigurationParameters = new Dictionary<string, string>();
        _service.LoadConfigurations().Completed += (s, e) =>
            {
                var loadOperation = (LoadOperation<Configuration>) s;
                foreach (Configuration configuration in loadOperation.Entities)
                {
                    ConfigurationParameters[configuration.ParameterKey] = configuration.ParameterValue;
                }
            };
    }
    private IDictionary<string, string> ConfigurationParameters { get; set; }
    public string this[string key]
    {
        get
        {
            return ConfigurationParameters[key];
        }
    }
}
Now I would like to use Unity to inject this instance of my repository into the IValueConverter instance...
App.xaml.cs:
private void RegisterTypes()
{
    _container = new UnityContainer();
    IConfigurationsRepository configurationsRepository = new ConfigurationRepository();
    _container.RegisterInstance<IConfigurationsRepository>(configurationsRepository);
}
IValueConverter:
public class SomeValueToBrushConverter : IValueConverter
{
    [Dependency]
    private ConfigurationRepository ConfigurationRepository { get; set; }
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
       switch ((SomeValue)value)
        {
            case SomeValue.Occupied:
                return new SolidColorBrush(ConfigurationRepository[OccupiedColor]);
            default:
                throw new ArgumentException();
        }
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
The problem is, that I do not get the same Unity-Container in the converter instance (ie. the repository is not registered).
It is possible to use a MarkupExtension for resolving the dependencies from an DI container:
public class IocResolver : MarkupExtension
{
    public IocResolver()
    { }
    public IocResolver(string namedInstance)
    {
        NamedInstance = namedInstance;
    }
    [ConstructorArgument("namedInstance")]
    public string NamedInstance { get; set; }
    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        var provideValueTarget = (IProvideValueTarget)serviceProvider
            .GetService(typeof(IProvideValueTarget));
        // Find the type of the property we are resolving
        var targetProperty = provideValueTarget.TargetProperty as PropertyInfo;
        if (targetProperty == null)
            throw new InvalidProgramException();
        Debug.Assert(Resolve != null, "Resolve must not be null. Please initialize resolving method during application startup.");
        Debug.Assert(ResolveNamed != null, "Resolve must not be null. Please initialize resolving method during application startup.");
        // Find the implementation of the type in the container
        return NamedInstance == null
            ? (Resolve != null ? Resolve(targetProperty.PropertyType) : DependencyProperty.UnsetValue)
            : (ResolveNamed != null ? ResolveNamed(targetProperty.PropertyType, NamedInstance) : DependencyProperty.UnsetValue);
    }
    public static Func<Type, object> Resolve { get; set; }
    public static Func<Type, string, object> ResolveNamed { get; set; }
}
The IocResolver have to be initialized during application startup like:
IocResolver.Resolve = kernel.Get; 
IocResolver.ResolveNamed = kernel.GetNamed;
// or what ever your DI container looks like
After that, you can use it in XAML to inject dependency in XAML:
<!-- Resolve an instance based on the type of property 'SomeValueToBrushConverter' -->
<MyConverter SomeValueToBrushConverter="{services:IocResolver}" />
<!-- Resolve a named instance based on the type of property 'SomeValueToBrushConverter' and the name 'MyName' -->
<MyConverter SomeValueToBrushConverter="{services:IocResolver  NamedInstance=MyName}" />
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With