首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在mvc3中使用简单注入器注册自定义ModelMetadataProvider

如何在mvc3中使用简单注入器注册自定义ModelMetadataProvider
EN

Stack Overflow用户
提问于 2012-08-15 14:28:29
回答 1查看 3.7K关注 0票数 3

当我尝试使用简单注入器注册模型元数据提供程序时,我没有得到任何错误,但是当我访问该实例时,它是mvc中默认的实例。

我尝试注册这个简单的注入器的方法是:

代码语言:javascript
复制
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>();
    }

}

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-08-15 15:23:51

如果我没记错的话,您必须显式地将您的自定义元数据提供程序注册到MVC:

代码语言:javascript
复制
ModelMetadataProviders.Current =
    new MyMetadataProvider();

如果您还需要将此实例注入到从容器解析的类型中,则还需要在容器中注册它:

代码语言:javascript
复制
ModelMetadataProviders.Current =
    new MyMetadataProvider();

container.RegisterSingle<ModelMetadataProvider>(
    ModelMetadataProviders.Current);

如果您希望容器将依赖项注入到您的自定义MyMetadataProvider中,则需要执行以下操作:

代码语言:javascript
复制
container.RegisterSingle<ModelMetadataProvider, MyMetadataProvider>();

container.Verify();

// Call this after you're done configuring the container.
ModelMetadataProviders.Current = 
   container.GetInstance<ModelMetadataProvider>();

因为ModelMetadataProviders.Current是单例的,所以ModelMetadataProvider必须是单例的,或者至少,在应用程序的生命周期内对其进行缓存并从多个线程同时访问它应该不是问题。当您向其中注入依赖项时,这可能不适合您的自定义提供程序(因为这些依赖项的生命周期可能比单例生活方式短)。

在这种情况下,您应该创建一个回调到DependencyResolver的代理提供程序

代码语言:javascript
复制
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属性中。

在这种情况下,您的配置如下所示:

代码语言:javascript
复制
// register the proxy that calls back into the container.
ModelMetadataProviders.Current =
    new DependencyResolverModelMetadataProvider();

// Register it as transient.
container.Register<ModelMetadataProvider, MyMetadataProvider>();

如果您希望您的自定义提供程序装饰原始提供程序,则需要将此原始提供程序注入到您的自定义提供程序的属性中(还有其他方法,但这是最简单的方法):

代码语言:javascript
复制
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注册为装饰器类:

代码语言:javascript
复制
container.RegisterSingle<ModelMetadataProvider>(
    ModelMetadataProviders.Current);

container.RegisterDecorator(
    typeof(ModelMetadataProvider),
    typeof(MyMetadataProvider));

ModelMetadataProviders.Current =
    new DependencyResolverModelMetadataProvider();

通过将MyMetadataProvider注册为装饰器,它将被包装在原始注册的ModelMetadataProvider (将被注入到MyMetadataProvider中。您将需要SimpleInjector.Extensions.dll项目来获取RegisterDecorator扩展。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11964956

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档