繁体   English   中英

通过Scan方法向StructureMap注册类型

[英]Registering types with StructureMap via Scan method

我在其他程序集中有IService接口和许多IService实现。 我需要将所有实现注册为IService和具体IService实现之间的继承链中类型的服务。 例如:

public interface IService{}
public abstract class BaseService<T>: IService{}

在另一个程序集中:

public class SomeSpecialService: BaseService<SomeType>{}
public class AnotherSpecialService: BaseService<AnotherType>{}

所以,我需要注册SomeSpecialService作为服务BaseService<SomeType>AnotherSpecialService作为服务BaseService<AnotherType>

目前,我通过反思来实现此目的,一个一个地注册每个实现。

1)是否可以使用Scan()表达式?

2)如果SomeSpecialService是另一个程序集中的内部(非公共)类,是否可以使用Scan()表达式?

您可以执行以下操作:

        var container = new Container(
            c => c.Scan(
                s =>
                    {
                        s.TheCallingAssembly();
                        s.AddAllTypesOf(typeof(BaseService<>));
                    }));

如果您针对具体的通用参数使用BaseService<>多种实现(例如BaseService<SomeType> ),则需要命名注册并按名称解析它们。

        var container = new Container(
            c => c.Scan(
                s =>
                    {
                        s.TheCallingAssembly();
                        s.AddAllTypesOf(typeof(BaseService<>)).NameBy(t => t.Name);
                    }));

        var service = container.GetInstance<BaseService<SomeType>>("BaseServiceForSomeType");

如果每个通用参数只有一个实现,并且您需要默认生命周期(瞬态)之外的其他实现,则可以使用s.ConnectImplementationsToTypesClosing(typeof(BaseService<>)).OnAddedPluginTypes(c => c.Singleton());

如果在注册类型时需要更多自定义,则可以定义注册约定。

        public class BaseServiceConvention : IRegistrationConvention
        {
            public void Process(Type type, Registry registry)
            {
                if (!type.IsConcrete())
                {
                    return;
                }

                var interfaceTypes = type.FindInterfacesThatClose(typeof(BaseService<>));

                foreach (var closedGenericType in interfaceTypes)
                {
                    if (GenericsPluginGraph.CanBeCast(closedGenericType, type))
                    {
                        registry.For(closedGenericType).Singleton().Use(type).Named(type.Name);
                    }
                }
            }
        }

您可以像这样应用此约定:

        var container = new Container(
                c => c.Scan(
                    s =>
                        {
                            s.TheCallingAssembly();
                            s.Convention<BaseServiceConvention>();
                        }));

希望这可以帮助!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM