自定义ModelMetadataProvider是单例,但依赖于请求范围的服务

时间:2012-10-05 18:38:11

标签: asp.net-mvc asp.net-mvc-3 ninject ioc-container

在我的ASP.NET MVC项目中,我有一个需要服务PropertyAccess的自定义ModelMetadataProvider。我目前正在使用构造函数注入和IOC容器(Ninject)来执行脏工作。问题是PropertyAccess是请求作用域,而我的ModelMetadataProvider只创建一次(在应用程序启动时)。这会导致PropertyAccess服务过期/不正确。

如果重要,以下是我在Global.asax中设置ModelMetadataProvider的方法:

private void RegisterModelMetadataProvider()
{
    var metadataProvider = DependencyResolver.Current.GetService<CustomModelMetadataProvider>();
    ModelMetadataProviders.Current = metadataProvider;
}

1 个答案:

答案 0 :(得分:1)

[我正在回答我自己的问题(Q&amp; A风格),但我不相信这是一个理想的解决方案。如果您有更好的方法(例如只需要配置的方式),请发表评论或留下替代答案。]

不是将PropertyAccess直接传递到单例类,而是传递PropertyAccessLocator,可以根据需要使用PropertyAccess来获取当前请求的public class PropertyAccessLocator { public PropertyAccess Get() { return DependencyResolver.Current.GetService<PropertyAccess>(); } }

这是PropertyAccessLocator

public class CustomModelMetadataProvider : DataAnnotationsModelMetadataProvider
{
    private readonly PropertyAccessLocator _propertyAccessLocator;

    public CustomModelMetadataProvider(
        PropertyAccessLocator propertyAccessLocator)
    {
        _propertyAccessLocator = propertyAccessLocator;
        // required because PropertyAccess is request scoped
        // while this class is a singleton 
    }

    protected override ModelMetadata CreateMetadata(
        IEnumerable<Attribute> attributes,
        Type containerType,
        Func<object> modelAccessor,
        Type modelType,
        string propertyName)
    {
        var metadata = base.CreateMetadata(
            attributes, containerType, modelAccessor, modelType, propertyName);
        var propertyAccess = _propertyAccessLocator.Get();
        // todo use propertyAccess to do something with the metadata...
        return metadata;
    }
}

以下是ModelMetadataProvider

的示例
{{1}}