Search code examples
c#unity-containerioc-containersilverlight-5.0ivalueconverter

Using Unity to inject objects into IValueConverter instance


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).


Solution

  • According to your comment, you need to use a ServiceLocator to get an instance of your ConfigurationRepository, cause the instance of the Converter isn´t created by Unity, but by the Silverlight/XAML engine.

    So your property that is decorated with the DependencyAttribute won´t be injected.

    c#

    public class SomeValueToBrushConverter : IValueConverter
    {
        public SomeValueToBrushConverter(){
          ConfigurationRepository = ServiceLocator.Current.GetInstance<ConfigurationRepository>();
        }
    
        private ConfigurationRepository ConfigurationRepository { get; set; }
    }
    

    In your RegisterTypes method you need to configure the ServiceLocator:

    _container = new UnityContainer();
    UnityServiceLocator locator = new UnityServiceLocator(_container);
    ServiceLocator.SetLocatorProvider(() => locator);