fro*_*hli 6 c# ioc-container unity-container ivalueconverter silverlight-5.0
我在Silverlight 5项目中有一个IValueConverter实例,它将自定义数据转换为不同的颜色.我需要从数据库中读取实际的颜色值(因为这些可以由用户编辑).
由于Silverlight使用异步调用通过Entity Framework从数据库加载数据,因此我创建了一个简单的存储库,它保存数据库中的值.
界面:
public interface IConfigurationsRepository
{
string this[string key] { get; }
}
Run Code Online (Sandbox Code Playgroud)
实施:
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];
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在我想使用Unity将我的存储库实例注入IValueConverter实例...
App.xaml.cs:
private void RegisterTypes()
{
_container = new UnityContainer();
IConfigurationsRepository configurationsRepository = new ConfigurationRepository();
_container.RegisterInstance<IConfigurationsRepository>(configurationsRepository);
}
Run Code Online (Sandbox Code Playgroud)
的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();
}
}
Run Code Online (Sandbox Code Playgroud)
问题是,我没有在转换器实例中获得相同的Unity-Container(即存储库未注册).
可以使用a 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; }
}
Run Code Online (Sandbox Code Playgroud)
必须在应用程序启动期间初始化IocResolver,如:
IocResolver.Resolve = kernel.Get;
IocResolver.ResolveNamed = kernel.GetNamed;
// or what ever your DI container looks like
Run Code Online (Sandbox Code Playgroud)
之后,您可以在XAML中使用它在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}" />
Run Code Online (Sandbox Code Playgroud)
根据您的评论,您需要使用 ServiceLocator 来获取 ConfigurationRepository 的实例,因为 Converter 的实例不是由 Unity 创建的 xc2xb4t,而是由 Silverlight/XAML 引擎创建。
\n\n因此,用 DependencyAttribute 修饰的属性将不会被注入\xc2\xb4t。
\n\nC#
\n\npublic class SomeValueToBrushConverter : IValueConverter\n{\n public SomeValueToBrushConverter(){\n ConfigurationRepository = ServiceLocator.Current.GetInstance<ConfigurationRepository>();\n }\n\n private ConfigurationRepository ConfigurationRepository { get; set; }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n在您的 RegisterTypes 方法中,您需要配置 ServiceLocator:
\n\n_container = new UnityContainer();\nUnityServiceLocator locator = new UnityServiceLocator(_container);\nServiceLocator.SetLocatorProvider(() => locator);\n
Run Code Online (Sandbox Code Playgroud)\n
归档时间: |
|
查看次数: |
3513 次 |
最近记录: |