UnityConfiguration的AssembliesInBaseDirectory方法解释了

时间:2014-11-15 21:30:05

标签: inversion-of-control unity-container

我需要有人向我解释一下AssembliesInBaseDirectory方法究竟返回了什么。我继承了一个具有以下代码的应用程序:

namespace Infrastructure.Common {

    public static class GlobalContainer
    {
        private static IUnityContainer _unityContainer;

        public static IUnityContainer CreateUnityContainer()
        {
            var unityContainer = new UnityContainer();

            unityContainer.Configure(unityRegistry => unityRegistry.AddRegistry<CommonRegistry>());

            return unityContainer;
        }

        public static IUnityContainer Unity
        {
            get { return _unityContainer ?? (_unityContainer = CreateUnityContainer()); }
            set { _unityContainer = value; } // For testability
        }
    }
}

这个GlobalContainer注册了另一个名为CommonRegistry的注册表,这是代码:

namespace Infrastructure.Common
{
    public class CommonRegistry : IocRegistry
    {
        public CommonRegistry()
        {
            const StringComparison strCmp = StringComparison.InvariantCultureIgnoreCase;

            Scan(scan =>v{  
                scan.AssembliesInBaseDirectory(a => a.GetName().Name.StartsWith(@"Pharmacy.", strCmp)
                    || a.GetName().Name.StartsWith(@"PharmacyServer.", strCmp)
                    || a.GetName().Name.StartsWith(@"CDM.", strCmp)
                    || a.GetName().Name.StartsWith(@"Commerce.", strCmp)
                    || a.GetName().Name.StartsWith(@"Infrastructure.", strCmp)
                    || a.GetName().Name.StartsWith(@"Audit.", strCmp)
                    || a.GetName().Name.StartsWith(@"Authentication.", strCmp)
                    || a.GetName().Name.StartsWith(@"LaSuite", strCmp));
                scan.ForRegistries(); 
            });
        }

        protected override void Register() 
        {
            RegisterWithConstructor<IUserContextProvider, UserContextProvider>(new IocInjectionConstructor());
            RegisterWithConstructor<ITenantProvider, TenantProvider>(new IocInjectionConstructor(new IocResolver<IUserContextProvider>()));
            Register<IImageProcessor, ImageProcessor>();
            Register<IValidationHelper, ValidationHelper>();
            Register<IClaimingHelper, ClaimingHelper>();
            Register<ICertificateHelper, CertificateHelper>();
        }
    }
}

我正在尝试理解对scan.AssembliesInBaseDirectory的调用。你看,我的解决方案有许多使用GlobalContainer的项目。一些是WCF服务,一些是控制台应用程序。我想知道,当从WCF服务调用此方法时,正在扫描哪些程序集?在哪里看?当它在控制台应用程序中使用时,它在哪里看?在我看来,基本目录根据谁使用GlobalContainer而改变。它是否正在寻找以每个项目(WCF和控制台)内的给定字符串开头的程序集?我是Ioc的新手。

1 个答案:

答案 0 :(得分:0)

看起来您正在使用Unity Configuration nuget包。

如果查看github中的源代码,您会看到以下内容:

public void AssembliesInBaseDirectory(Predicate<Assembly> predicate)
{
    AssembliesInDirectory(AppDomain.CurrentDomain.BaseDirectory, predicate);
    AssembliesInDirectory(AppDomain.CurrentDomain.SetupInformation.PrivateBinPath, predicate);
}

这意味着代码正在查看以下目录:

  • AppDomain.CurrentDomain.BaseDirectory,这是加载当前应用程序域的目录(如exe目录或ASP.Net中的根文件夹)。请参阅this

  • AppDomain.CurrentDomain.SetupInformation.PrivateBinPath,这是针对私有程序集探测的应用程序基目录下的目录列表。请参阅this

对于在这些目录中找到的所有程序集,过滤所有不以给定字符串开头的程序集。因此,根据ScanForRegistriesConvention,将扫描以给定字符串开头的类型,以便继承UnityRegistry的类型。这些注册表将有一个构造函数,其中的类型将在Unity中注册。