2011-01-31 57 views
7

我有以下接口:Autofac。如何使用自定義方法(屬性)來解析某個接口?

public interface IConfigurationProvider<TSettings> where TSettings : ISettings, new() 
{ 
     TSettings Settings { get; } 
} 
public interface ISettings 
{ 
} 

我有以下實現IConfigurationProvider的:

public class ConfigurationProvider<TSettings> : IConfigurationProvider<TSettings> where 

    TSettings : ISettings, new() 
     { 
      public ConfigurationProvider() 
      { 
       this.BuildConfiguration(); 
      } 

      public TSettings Settings { get; private set; } 

      private void BuildConfiguration() 
      { 
       this.Settings = new TSettings(); 
       //...load and assign properties to 'this.Settings' 
       //...skipped 
       // now 'Settings' property contains configured 'ISettings' instance 
      } 
     } 

我也可以有不同的類實現 'ISettings' 界面。例如,

public class UserSettings : ISettings 
    { 
     public int SomeProperty1 { get; set; } 
     public int SomeProperty2 { get; set; } 
    } 


public class CatalogSettings : ISettings 
    { 
     public int SomeProperty3 { get; set; } 
     public int SomeProperty4 { get; set; } 
    } 

我用下面的代碼來配置 'ContainerBuilder':builder.RegisterGeneric(typeof(ConfigurationProvider<>)).As(typeof(IConfigurationProvider<>));

它工作正常。而爲了得到「UserSettings」我用下面的代碼:

var userSettingsProvider = builder.Resolve<IConfigurationProvider<UserSettings>>(); 
var userSettings = userSettingsProvider.Settings; 

的問題:我應該如何配置「ContainerBuilder」這樣我就可以解決一定的「ISettings」方式如下:

var userSettings = builder.Resolve<UserSettings>(); 

Autofac可以嗎?

在此先感謝

回答

5

您可以用IRegistrationSource做到這一點 - 看到http://nblumhardt.com/2010/01/declarative-context-adapters-autofac2/的概述。

的基本結構是:

class SettingsSource : IRegistrationSource { 
    static readonly MethodInfo BuildMethod = typeof(SettingsSource).GetMethod(
     "BuildRegistration", 
     BindingFlags.Static | BindingFlags.NonPublic); 

    public IEnumerable<IComponentRegistration> RegistrationsFor(
      Service service, 
      Func<Service, IEnumerable<IComponentRegistration>> registrations) { 
     var ts= service as TypedService; 
     if (ts != null && typeof(ISettings).IsAssignableFrom(ts.ServiceType) { 
      var buildMethod = BuildMethod.MakeGenericMethod(ts.ServiceType); 
      yield return (IComponentRegistration) buildMethod.Invoke(null, null); 
     } 
    } 

    static IComponentRegistration BuildRegistration<TSettings>() 
      where TSettings : ISettings { 
     return RegistrationBuilder 
      .ForDelegate((c, p) => 
       c.Resolve<IConfigurationProvider<TSettings>>().Settings) 
      .CreateRegistration(); 
    } 

    public bool IsAdapterForIndividualComponents { get { return false; } } 
} 

這是註冊像這樣:

builder.RegisterGeneric(typeof(ConfigurationProvider<>)) 
    .As(typeof(IConfigurationProvider<>)); 
builder.RegisterSource(new SettingsSource()); 

(沒有編譯或測試,所以讓我知道,如果它倒了;))

+0

感謝您的回覆。我在BuildRegistration()方法中遇到了以下編譯錯誤「無法隱式地將類型'Autofac.Builder.IRegistrationBuilder '轉換爲'Autofac.Core.IComponentRegistration'' 。 – 2011-02-01 07:23:39