gpt4 book ai didi

c# - 使用 Unity 将对象注入(inject) IValueConverter 实例

转载 作者:太空狗 更新时间:2023-10-29 21:29:14 25 4
gpt4 key购买 nike

我在 Silverlight 5 项目中有一个 IValueConverter 实例,它将自定义数据转换为不同的颜色。我需要从数据库中读取实际颜色值(因为这些可以由用户编辑)。

由于 Silverlight 使用异步调用通过 Entity Framework 从数据库加载数据,我创建了一个简单的存储库,它保存来自数据库的值。

界面:

public interface IConfigurationsRepository
{
string this[string key] { get; }
}

实现:

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];
}
}
}

现在我想使用 Unity 将我存储库的这个实例注入(inject)到 IValueConverter 实例中......

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();
}
}

问题是,我在转换器实例中没有得到相同的 Unity-Container(即存储库未注册)。

最佳答案

可以使用 MarkupExtension 来解决来自 DI 容器的依赖关系:

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; }
}

IocResolver 必须在应用程序启动期间初始化,例如:

IocResolver.Resolve = kernel.Get; 
IocResolver.ResolveNamed = kernel.GetNamed;
// or what ever your DI container looks like

之后,你可以在XAML中使用它来在XAML中注入(inject)依赖:

<!-- 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}" />

关于c# - 使用 Unity 将对象注入(inject) IValueConverter 实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10278044/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com