2013-02-12 67 views
2

我正在寻找一种将设置合并到我的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。我尝试了几件事来获得正确的绑定,但似乎无法找到正确的实现。有没有人有一个想法如何得到这个工作?

编辑

我找到了一种方法来直接绑定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。有人知道如何纠正这个问题吗?

最后的编辑

我不知道为什么,但突然它的工作原理!很高兴我终于明白了。 Thanx Remo!

回答

1

您有几种选择:

  1. 做到像NopCommerce和扫描设置类别和使用反射从你第一次编辑调用注册方法。
  2. 使用约定延长登记使用自定义绑定发生器https://github.com/ninject/ninject.extensions.conventions/wiki/Projecting-Services-to-Bind
  3. 使用约定延长注册实施ISettings绑定所有接口类实现ISettings所有类。并且添加一个自定义的IActivationStrategy到Ninject,它可以分配像NopCommerce这样的属性。