Я ищу хороший способ включить настройки внутри моего webapp (asp mvc). Я натолкнулся на действительно приятную реализацию в NopCommerce. NopCommerce сохраняет значения в таблице базы данных с именем и значением. Название происходит от имени класса и свойств (например, customersettings.settingname1)Взаимодействие с дженериками и недвижимостью в Ninject
Точный способ NopCommerce работы с настройками можно найти в этом вопросе: Understanding how Nop Commerce settings are loaded from the database
NopCommerce использует Autofac в рамках DI привязать Settings
к ConfigurationProvider
следующим образом (как я прав).
return RegistrationBuilder
.ForDelegate((c, p) => c.Resolve<IConfigurationProvider<TSettings>>().Settings)
.InstancePerHttpRequest()
.CreateRegistration();
В соответствующих классах, теперь вы можете использовать ClientSettings
в качестве параметра, и он автоматически заполняется данными из базы данных.
Мне очень нравится эта реализация, потому что она очень гибкая. Однако проблема заключается в том, что я использую Ninject. Я попробовал несколько вещей, чтобы получить правильные привязки, но не могу найти правильную реализацию. Кто-нибудь есть идея, как заставить это работать?
EDIT:
Я нашел способ связать ClientSettings
непосредственно:
kernel.Bind<ClientSettings>()
.ToMethod(ctx => ctx.Kernel.Get<IConfigurationProvider<ClientSettings>>().Settings)
.InRequestScope();
Но есть способ для достижения этой цели?
kernel.Bind<ISettings>()
.ToMethod(ctx => ctx.Kernel.Get<IConfigurationProvider<ISettings>>().Settings)
.InRequestScope();
EDIT 2
Я думаю, что я близко, но все же столкнуться с некоторыми проблемами. Я создаю специальный генератор связи:
public class SettingsBindGenerator : IBindingGenerator
{
static readonly MethodInfo BuildMethod = typeof(SettingsBindGenerator).GetMethod(
"BuildRegistration",
BindingFlags.Static | BindingFlags.NonPublic);
public IEnumerable<IBindingWhenInNamedWithOrOnSyntax<object>> CreateBindings(Type type, IBindingRoot bindingRoot)
{
var obj = typeof (object).IsAssignableFrom(type);
if (type != null && typeof(ISettings).IsAssignableFrom(type))
{
var buildMethod = BuildMethod.MakeGenericMethod(type);
var methodResult = buildMethod.Invoke(null, new object[]{bindingRoot});
var castedResult = methodResult as IBindingWhenInNamedWithOrOnSyntax<object>;
yield return castedResult;
}
}
static IBindingWhenInNamedWithOrOnSyntax<TSettings> BuildRegistration<TSettings>(IBindingRoot bindingRoot) where TSettings : ISettings, new()
{
return bindingRoot.Bind<TSettings>().ToMethod(
ctx => ctx.Kernel.Get<IConfigurationProvider<TSettings>>().Settings);
}
}
Это работает на 99%. Однако по какой-то причине buildMethod.Invoke возвращает BindingConfigurationBuilder, а не IBindingWhenInNamedWithOrOnSyntax. Поэтому castedResult всегда имеет значение NULL. Кто-нибудь понял, как это исправить?
ПОСЛЕДНИЙ EDIT
Я не знаю, почему, но вдруг это работает! Рад, что я наконец понял это. Thanx Remo!