当我尝试使用简单注入器注册模型元数据提供程序时,我没有得到任何错误,但是当我访问该实例时,它是mvc中默认的实例。
我尝试注册这个简单的注入器的方法是:
public static class SimpleInjectorInitializer{
public static void Initialize(){
var container = new Container(new ContainerOptions AllowOverridingRegistrations = true});
InitializeContainer(container);
container.RegisterMvcControllers(Assembly.GetExecutingAssembly());
container.RegisterMvcAttributeFilterProvider();
container.Verify();
DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
}
private static void InitializeContainer(Container container){
container.Register<ModelMetadataProvider, MyMetadataProvider>();
}}
发布于 2012-08-15 15:23:51
如果我没记错的话,您必须显式地将您的自定义元数据提供程序注册到MVC:
ModelMetadataProviders.Current =
new MyMetadataProvider();如果您还需要将此实例注入到从容器解析的类型中,则还需要在容器中注册它:
ModelMetadataProviders.Current =
new MyMetadataProvider();
container.RegisterSingle<ModelMetadataProvider>(
ModelMetadataProviders.Current);如果您希望容器将依赖项注入到您的自定义MyMetadataProvider中,则需要执行以下操作:
container.RegisterSingle<ModelMetadataProvider, MyMetadataProvider>();
container.Verify();
// Call this after you're done configuring the container.
ModelMetadataProviders.Current =
container.GetInstance<ModelMetadataProvider>();因为ModelMetadataProviders.Current是单例的,所以ModelMetadataProvider必须是单例的,或者至少,在应用程序的生命周期内对其进行缓存并从多个线程同时访问它应该不是问题。当您向其中注入依赖项时,这可能不适合您的自定义提供程序(因为这些依赖项的生命周期可能比单例生活方式短)。
在这种情况下,您应该创建一个回调到DependencyResolver的代理提供程序
public DependencyResolverModelMetadataProvider : ModelMetadataProvider
{
public override IEnumerable<ModelMetadata> GetMetadataForProperties(
object container, Type containerType)
{
return GetProvider().GetMetadataForProperties(
container, containerType);
}
public override ModelMetadata GetMetadataForProperty(
Func<object> modelAccessor, Type containerType, string propertyName)
{
return GetProvider().GetMetadataForProperty(
modelAccessor, containerType, propertyName);
}
public override ModelMetadata GetMetadataForType(
Func<object> modelAccessor, Type modelType)
{
return GetProvider().GetMetadataForType(
modelAccessor, modelType);
}
private static ModelMetadataProvider GetProvider()
{
return (ModelMetadataProvider)
DependencyResolver.Current.GetService(
typeof(ModelMetadataProvider));
}
}由于此代理将在每次调用时调用DependencyResolver (并且不包含任何状态),因此您可以安全地创建单个实例并将其存储到ModelMetadataProviders.Current属性中。
在这种情况下,您的配置如下所示:
// register the proxy that calls back into the container.
ModelMetadataProviders.Current =
new DependencyResolverModelMetadataProvider();
// Register it as transient.
container.Register<ModelMetadataProvider, MyMetadataProvider>();如果您希望您的自定义提供程序装饰原始提供程序,则需要将此原始提供程序注入到您的自定义提供程序的属性中(还有其他方法,但这是最简单的方法):
var original = ModelMetadataProviders.Current;
// register the proxy that calls back into the container.
ModelMetadataProviders.Current =
new DependencyResolverModelMetadataProvider();
// Register it as transient.
container.Register<ModelMetadataProvider, MyMetadataProvider>();
container.RegisterInitializer<MyMetadataProvider>(prov =>
{
// The decorated provider is put as a property on the
// MyMetadataProvider class.
prov.DecoratedProvider = original;
});另一种方法是将自定义MyMetadataProvider注册为装饰器类:
container.RegisterSingle<ModelMetadataProvider>(
ModelMetadataProviders.Current);
container.RegisterDecorator(
typeof(ModelMetadataProvider),
typeof(MyMetadataProvider));
ModelMetadataProviders.Current =
new DependencyResolverModelMetadataProvider();通过将MyMetadataProvider注册为装饰器,它将被包装在原始注册的ModelMetadataProvider (将被注入到MyMetadataProvider中。您将需要SimpleInjector.Extensions.dll项目来获取RegisterDecorator扩展。
https://stackoverflow.com/questions/11964956
复制相似问题