Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在自定义DisplayFormatAttribute中注入一些服务_C#_Asp.net Mvc_Asp.net Mvc 5_Autofac - Fatal编程技术网

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

C# 在自定义DisplayFormatAttribute中注入一些服务,c#,asp.net-mvc,asp.net-mvc-5,autofac,C#,Asp.net Mvc,Asp.net Mvc 5,Autofac,希望这不是重复 我正在使用Autofac 我正在努力在我的自定义属性XNameDisplayFormatAttribute中注入一些服务,该属性继承自DisplayFormatAttribute。我想从数据库中获取一些数据,这些数据与登录用户的当前文化信息有关。为此,我创建了一个设置服务,但问题是我无法将其注入xnamesplayformattribute。我读到没有办法在属性(不是过滤器)中注入服务,但有解决方法(不太确定如何!)。我的自定义属性将如下所示: [AttributeUsage(A

希望这不是重复

我正在使用
Autofac

我正在努力在我的自定义属性
XNameDisplayFormatAttribute
中注入一些服务,该属性继承自
DisplayFormatAttribute
。我想从数据库中获取一些数据,这些数据与登录用户的当前文化信息有关。为此,我创建了一个
设置服务
,但问题是我无法将其注入
xnamesplayformattribute
。我读到没有办法在属性(不是过滤器)中注入服务,但有解决方法(不太确定如何!)。我的自定义属性将如下所示:

[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>();

我认为你的设计有一些缺陷

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

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

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

在应用程序启动时,在Autofac设置之后,立即将DisplayFormatManager注入到
XNameDisplayFormatAttribute
类的静态属性中。那么,希望最好的结果是:我不知道什么时候会使用属性值

然而,我会寻找一条不同的路径:如果配置是动态的,那么应该通过代码来处理,而不是通过元数据,依我看。你的里程可能会有很大的不同

[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);
}
[AttributeUsage(AttributeTargets.Property,AllowMultiple=true)]
公共类XNameDisplayFormatAttribute:DisplayFormatAttribute
{
公共静态DisplayFormatManager FormatsManager{get;set;}
公共XNameDisplayFormatAttribute(bool applyFormatInEditMode=true)
{
DataFormatString=FormatsManager.GetDataFromDb(\u DataFormatString);
ApplyFormatInEditMode=ApplyFormatInEditMode;
}
私有字符串dataFormatString;
公共新字符串DataFormatString
{
get=>FormatsManager.GetDataFromDb(\u dataFormatString);
set=>\u dataFormatString=value;
}
}
公共类显示格式管理器
{
公共显示格式管理器(功能设置服务工厂)
{
设置服务工厂=设置服务工厂;
}
公共函数设置服务工厂{get;}
公共字符串GetDataFromDb(字符串格式)
{
var服务=设置服务工厂();
return service.GetDataFromDb(格式);
}
}
公共接口设置服务
{
字符串GetDataFromDb(字符串格式);
}

您可以将服务注入到操作筛选器中

除非您使用服务定位器反模式,否则没有其他方法将服务注入该属性。@Nkosi您指的是像我在“编辑”部分中所做的那样获取服务吗?是的,这就是我指的。@Nkosi它不起作用,唯一不起作用的地方正是在该属性中,因为在其他地方与扩展方法等类似,它工作正常。我更新配置部分。你认为我需要补充什么吗?这可能与ASP.MVC在属性上的特定行为有关:(您是否已向容器注册了
ISettingsService
[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);
}