减少根据数据类型获取设置的方法数量
Decrease amount of methods to get settings based on data type
所以我有一个 table 可以让我的移动应用程序的设置在开发接近尾声时保持不变,我忍不住认为这是一种更简洁的方法。
我将如何进行一次调用来解释返回的不同数据类型,而不是进行三个单独的调用。
我在 Web api 项目中使用 ef core 6 和 c# 7。
public class SettingsService
{
TheAppDBContext db;
public SettingsService(TheAppDBContext dBContext)
{
db = dBContext;
}
public List<Settings> GetALLSettings()
{
return db.Settings.Where(w => w.IsActive == true &&
w.IsDeleted == false).ToList();
}
public bool? GetBoolSettingValueByKey(string Key)
{
return db.Settings.Where(w => w.IsActive == true && w.IsDeleted == false
&& w.Key.ToLower() == Key.ToLower()).First().BoolValue;
}
public string? GetStringSettingValueByKey(string Key)
{
return db.Settings.Where(w => w.IsActive == true && w.IsDeleted == false &&
w.Key.ToLower() == Key.ToLower()).First().StringValue;
}
public int? GetIntSettingValueByKey(string Key)
{
return db.Settings.Where(w => w.IsActive == true && w.IsDeleted == false &&
w.Key.ToLower() == Key.ToLower()).First().IntValue;
}
}
我的 Table 设置如下,将来可能会在设置 table 中存储日期和其他数据类型。
如果您愿意失去一些类型安全性,您可以使用使您的方法成为通用方法并分析它的通用类型参数:
public T GetSettingValueByKey<T>(string key)
{
var setting = db.Settings
.Where(w => w.IsActive == true && w.IsDeleted == false && w.Key.ToLower() == Key.ToLower())
.First();
var type = typeof(T);
if (type == typeof(bool))
{
return (T)(object)setting.BoolValue;
}
if (type == typeof(string))
{
return (T)(object)setting.StringValue;
}
if (type == typeof(int))
{
return (T)(object)setting.IntValue;
}
...
throw new InvalidOperationException();
}
这里的问题是没有人限制用户使用不受支持的类型调用 GetSettingValueByKey
并且编译器无法强制执行(除非您想深入编写自定义代码分析器)。
为了在没有自定义分析器的情况下保持编译时安全,您可以尝试引入类型层次结构来表示可能的设置类型:
public interface ISettingValue{}
public interface ISettingValue<T> : ISettingValue
{
T Value { get; set; }
}
public struct IntSettingValue : ISettingValue<int?>
{
public int? Value { get; set; }
}
public struct BoolSettingValue : ISettingValue<bool?>
{
public bool? Value { get; set; }
}
...
public T GetSettingValueByKey<T>(string key) where T : ISettingValue
{
var setting = db.Settings
.Where(w => w.IsActive == true && w.IsDeleted == false && w.Key.ToLower() == Key.ToLower())
.First();
var type = typeof(T);
if (type == typeof(BoolSettingValue))
{
return (T)(object)new BoolSettingValue
{
Value = setting.BoolValue
};
}
if (type == typeof(int))
{
return (T)(object)new IntSettingValue
{
Value = setting.IntValue
};
}
...
throw new InvalidOperationException(); // write unit test with reflection to validate that this never happens
}
和用法:
SettingsService service = ...;
int? val = service.GetSettingValueByKey<IntSettingValue>("").Value;
所以我有一个 table 可以让我的移动应用程序的设置在开发接近尾声时保持不变,我忍不住认为这是一种更简洁的方法。
我将如何进行一次调用来解释返回的不同数据类型,而不是进行三个单独的调用。
我在 Web api 项目中使用 ef core 6 和 c# 7。
public class SettingsService
{
TheAppDBContext db;
public SettingsService(TheAppDBContext dBContext)
{
db = dBContext;
}
public List<Settings> GetALLSettings()
{
return db.Settings.Where(w => w.IsActive == true &&
w.IsDeleted == false).ToList();
}
public bool? GetBoolSettingValueByKey(string Key)
{
return db.Settings.Where(w => w.IsActive == true && w.IsDeleted == false
&& w.Key.ToLower() == Key.ToLower()).First().BoolValue;
}
public string? GetStringSettingValueByKey(string Key)
{
return db.Settings.Where(w => w.IsActive == true && w.IsDeleted == false &&
w.Key.ToLower() == Key.ToLower()).First().StringValue;
}
public int? GetIntSettingValueByKey(string Key)
{
return db.Settings.Where(w => w.IsActive == true && w.IsDeleted == false &&
w.Key.ToLower() == Key.ToLower()).First().IntValue;
}
}
我的 Table 设置如下,将来可能会在设置 table 中存储日期和其他数据类型。
如果您愿意失去一些类型安全性,您可以使用使您的方法成为通用方法并分析它的通用类型参数:
public T GetSettingValueByKey<T>(string key)
{
var setting = db.Settings
.Where(w => w.IsActive == true && w.IsDeleted == false && w.Key.ToLower() == Key.ToLower())
.First();
var type = typeof(T);
if (type == typeof(bool))
{
return (T)(object)setting.BoolValue;
}
if (type == typeof(string))
{
return (T)(object)setting.StringValue;
}
if (type == typeof(int))
{
return (T)(object)setting.IntValue;
}
...
throw new InvalidOperationException();
}
这里的问题是没有人限制用户使用不受支持的类型调用 GetSettingValueByKey
并且编译器无法强制执行(除非您想深入编写自定义代码分析器)。
为了在没有自定义分析器的情况下保持编译时安全,您可以尝试引入类型层次结构来表示可能的设置类型:
public interface ISettingValue{}
public interface ISettingValue<T> : ISettingValue
{
T Value { get; set; }
}
public struct IntSettingValue : ISettingValue<int?>
{
public int? Value { get; set; }
}
public struct BoolSettingValue : ISettingValue<bool?>
{
public bool? Value { get; set; }
}
...
public T GetSettingValueByKey<T>(string key) where T : ISettingValue
{
var setting = db.Settings
.Where(w => w.IsActive == true && w.IsDeleted == false && w.Key.ToLower() == Key.ToLower())
.First();
var type = typeof(T);
if (type == typeof(BoolSettingValue))
{
return (T)(object)new BoolSettingValue
{
Value = setting.BoolValue
};
}
if (type == typeof(int))
{
return (T)(object)new IntSettingValue
{
Value = setting.IntValue
};
}
...
throw new InvalidOperationException(); // write unit test with reflection to validate that this never happens
}
和用法:
SettingsService service = ...;
int? val = service.GetSettingValueByKey<IntSettingValue>("").Value;