在自定义DisplayFormatAttribute中注入一些服务

时间:2017-06-08 23:15:17

标签: c# asp.net-mvc asp.net-mvc-5 autofac

希望这不是重复的!

我正在使用Autofac

我正在努力在名为XNameDisplayFormatAttribute的自定义属性中注入一些服务,该属性继承自DisplayFormatAttribute。我的想法是,我希望从数据库中获取与登录用户的当前文化信息相关的一些数据。为此,我创建了一个SettingsService,但问题是我无法在XNameDisplayFormatAttribute中注入它。我读到如何在属性中注入服务( not filters ),但是有一些解决方法(不太确定如何!)。我的自定义属性如下所示:

[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
public class XNameDisplayFormatAttribute : DisplayFormatAttribute
{
    public ISettingsService SettingsService {get;set;}
    public XNameDisplayFormatAttribute (bool applyFormatInEditMode = true) 
    {
        DataFormatString = SettingsService.GetDataFromDb();"*My format retrieved from db*";
        ApplyFormatInEditMode = applyFormatInEditMode;
    }
}

这不能正常工作但我需要类似于这个逻辑的东西才能从数据库执行get动作。

有人知道如何实现这一目标吗?

如果可能的话,一个好主意不是搞乱过滤器,我想用适当的属性保持代码清晰。

修改

我也使用了下面的代码但是我只在属性中得到空值:

ISettingsService settings = DependencyResolver.Current.GetService<ISettingsService>();

这是我的配置部分:

public void Configuration(IAppBuilder app)
{
    var builder = new ContainerBuilder();
    RegisterStartUp.RegisterDependecies(builder, app);
    builder.RegisterControllers(Assembly.GetExecutingAssembly());
    //Registering model binders
    builder.RegisterModelBinders(Assembly.GetExecutingAssembly());
    builder.RegisterModelBinderProvider();

    //builder.RegisterSource(new ViewRegistrationSource());
    builder.RegisterFilterProvider();
    // BUILD THE CONTAINER
    var container = builder.Build();
    // REPLACE THE MVC DEPENDENCY RESOLVER WITH AUTOFAC
    DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
    // REGISTER WITH OWIN
    app.UseAutofacMiddleware(container);
    app.UseAutofacMvc();
    ConfigureAuth(app);
    app.MapSignalR();
}

2 个答案:

答案 0 :(得分:1)

我认为你的设计存在一些缺陷。

您正在使用一个属性来实现业务逻辑,但一个属性通常应该只包含元数据,并且有充分的理由:该属性以一种特殊的方式嵌入到程序集中,并且与其他类的处理方式不同。

您的想法的根本问题是,属性实际上意味着存储(并最终操作)编译时已知的数据。属性不是(并且,AFAICT,永远不会)像其他类一样实例化,因此deendency注入不适用。

我会尝试:实现一个DisplayFormatManager类并通过Autofac将其注册为单例。该类负责调用SettingsService并检索您需要的内容。

在应用程序启动时,在Autofac设置之后,将DisplayFormatManager注入XNameDisplayFormatAttribute类的静态属性。然后希望最好:我不知道何时将使用属性值。

我会搜索不同的路径,但是:如果配置是动态的,则应通过代码处理,而不是通过元数据IMO处理。您的里程可能会有很大差异。

[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
public class XNameDisplayFormatAttribute : DisplayFormatAttribute
{
    public static DisplayFormatManager FormatsManager { get; set; }

    public XNameDisplayFormatAttribute(bool applyFormatInEditMode = true)
    {
        DataFormatString = FormatsManager.GetDataFromDb(_dataFormatString);
        ApplyFormatInEditMode = applyFormatInEditMode;
    }

    private string _dataFormatString;
    public new string DataFormatString
    {
        get => FormatsManager.GetDataFromDb(_dataFormatString);
        set => _dataFormatString = value;
    }
}

public class DisplayFormatManager
{
    public DisplayFormatManager(Func<ISettingsService> settingsServiceFactory)
    {
        SettingsServiceFactory = settingsServiceFactory;
    }

    public Func<ISettingsService> SettingsServiceFactory { get; }

    public string GetDataFromDb(string format)
    {
        var service = SettingsServiceFactory();
        return service.GetDataFromDb(format);
    }
}

public interface ISettingsService
{
    string GetDataFromDb(string format);
}

答案 1 :(得分:0)