【问题标题】:Autofac. How to use custom method(property) to resolve some interface?自动法。如何使用自定义方法(属性)来解析某些接口?
【发布时间】:2011-01-31 14:05:56
【问题描述】:

我有以下接口:

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&lt;&gt;)).As(typeof(IConfigurationProvider&lt;&gt;));

它工作正常。为了获得“用户设置”,我使用以下代码:

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

问题:我应该如何配置“ContainerBuilder”,以便我可以通过以下方式解决某个“ISettings”:

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

Autofac 可以吗?

提前致谢

【问题讨论】:

    标签: c# autofac


    【解决方案1】:

    您可以通过 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());
    

    (未编译或测试,如果失败请告诉我;))

    【讨论】:

    • 感谢您的回复。我在 BuildRegistration() 方法中出现以下编译错误“无法将类型 'Autofac.Builder.IRegistrationBuilder' 隐式转换为 'Autofac.Core.IComponentRegistration'” .
    • 它就像一个魅力。谢谢。附言您忘记将 .CreateRegistration() 添加到“BuildRegistration()”方法中
    • 尼古拉斯,还有一个问题。当前,“ISetting”实例是根据依赖项创建的(默认行为)。如何将其更改为“InstancePerLifetimeScope”或“Ins​​tancePerHttpRequest”(已添加“Autofac.Integration.Mvc.dll”)
    • 谢谢 - 修复了语法错误。您可以在 .CreateRegistration() 调用之前使用 .InstancePerXx()。
    猜你喜欢
    • 1970-01-01
    • 2023-03-04
    • 2019-11-14
    • 2016-11-08
    • 1970-01-01
    • 2011-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多