2

ASP.NET MVCプロジェクトには、サービスを必要とするカスタムModelMetadataProviderがありますPropertyAccess。私は現在、コンストラクターインジェクションとIOCコンテナー(Ninject)を使用してダーティな作業を行っています。問題は、PropertyAccessリクエストスコープであるのに対し、ModelMetadataProviderは(アプリケーションの起動時に)一度だけ作成されることです。これにより、PropertyAccessサービスが古くなったり、正しくなくなったりします。

重要な場合は、Global.asaxでModelMetadataProviderを設定する方法を次に示します。

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

1 に答える 1

1

[私は自分の質問(Q&Aスタイル)に答えていますが、これが理想的な解決策であるとは確信していません。より良い方法(構成のみが必要な方法など)がある場合は、コメントするか、別の回答を残してください。]

PropertyAccessシングルトンクラスに直接渡す代わりに、を渡しますPropertyAccessLocator。これを使用して、PropertyAccess必要に応じて現在のリクエストのを取得できます。

これがPropertyAccessLocatorです

public class PropertyAccessLocator
{
    public PropertyAccess Get()
    {
        return DependencyResolver.Current.GetService<PropertyAccess>();
    }
}

ModelMetadataProviderの例を次に示します

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;
    }
}
于 2012-10-05T18:38:11.173 に答える