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);
}