2011-01-31 25 views
7

Tôi có giao diện như sau:Autofac. Làm thế nào để sử dụng phương thức tùy chỉnh (thuộc tính) để giải quyết một số giao diện?

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

Tôi có việc thực hiện sau đây của 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 
      } 
     } 

Tôi cũng có thể có các lớp học riêng biệt thực hiện giao diện 'ISettings'. Ví dụ,

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

Tôi đang sử dụng đoạn mã sau để cấu hình 'ContainerBuilder': builder.RegisterGeneric(typeof(ConfigurationProvider<>)).As(typeof(IConfigurationProvider<>));

Nó hoạt động tốt. Và để có được 'UserSettings' Tôi sử dụng đoạn mã sau:

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

Câu hỏi: làm thế nào tôi nên cấu hình 'ContainerBuilder' vì vậy tôi có thể giải quyết một số 'ISettings' theo cách sau:

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

Có thể với Autofac không?

Cảm ơn trước

Trả lời

5

Bạn có thể làm điều này với một IRegistrationSource - xem http://nblumhardt.com/2010/01/declarative-context-adapters-autofac2/ cho một cái nhìn tổng quan.

Cấu trúc cơ bản sẽ là:

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

này được đăng ký như sau:

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

(Không biên soạn hoặc thử nghiệm, vì vậy hãy cho tôi biết nếu nó té ngã hơn;))

+0

Cảm ơn bạn đã trả lời. Tôi nhận được lỗi biên dịch sau đây "Không thể chuyển đổi hoàn toàn loại 'Autofac.Builder.IRegistrationBuilder ' thành 'Autofac.Core.IComponentRegistration'" trong phương thức BuildRegistration() của bạn . –

+0

Nó hoạt động như một sự quyến rũ. Cảm ơn. P.S. Bạn quên thêm .CreateRegistration() vào "BuildRegistration ()" phương thức –

+0

Nickolas, một câu hỏi nữa. Hiện tại 'ISetting' thể hiện được tạo ra cho mỗi phụ thuộc (hành vi mặc định). Làm thế nào tôi có thể thay đổi nó thành 'InstancePerLifetimeScope' hoặc 'InstancePerHttpRequest' ('Autofac.Integration.Mvc.dll' đã được thêm) –

Các vấn đề liên quan