StructureMap 代码分析之Widget 之Registry 分析 (1)

  说句实话,本人基本上没用过Structuremap,但是这次居然开始看源码了,不得不为自己点个赞。Structuremap有很多的类,其中有一个叫做Widget的概念。那么什么是Widget呢?要明白什么是Widget,首先必须明白什么是Registry.而Registry又和Structuremap里面的Graph有着千丝万缕的联系。由于自己也才开始接触源码,所以可能有误导大家的地方,大家看看就好,不可盲目相信我说的,好我们先来看看下面这个类。

    public class MyRegistry : Registry
    {
        public MyRegistry()
        {
            Scan(
                x =>
                {
                    x.TheCallingAssembly();
                    x.Convention<MyConvention>();
                });
        }
    }

  我们来对上面的代码做一个梳理:首先是MyRegistry继承了Registry,那么当我们使用MyRegistry实例的时候,会自动对MyRegistry所注册的容器里面进行一层“扫描”,其实我觉得大家有必要来看看这个方法:

public void Scan(Action<IAssemblyScanner> action)

  Scan其实是一个带有无返回委托类型的一个Action,这里用到了IAssemblyScanner这个接口,下面我们来看一下这个接口里面到底有什么东西,下面的代码,官方的解释是向Scan操作添加程序集:

void Assembly(Assembly assembly);

void Assembly(string assemblyName);

  为了不陷入代码的圈套,我这里不决定讲太多的方法,就讲上面2个方法的实现好了,AssemblyScanner这个类实现了IAssemblyScanner这个接口,定义了如下全局变量,其中的Assembly是反射有关的类:

private readonly List<Assembly> _assemblies = new List<Assembly>();

  如果现有程序集不在程序集全局列表里,就添加它

       public void Assembly(Assembly assembly)
        {
            if (!_assemblies.Contains(assembly))
            {
                _assemblies.Add(assembly);
            }
        }

  这里用到了一个Structuremap的另一个类:AsseblyLoader,其实就是做了层封装而已.

        public void Assembly(string assemblyName)
        {
            Assembly(AssemblyLoader.ByName(assemblyName));
        }

  使用了Assembly.load的某个重载函数而已。

    public static class AssemblyLoader
    {
        public static Assembly ByName(string assemblyName)
        {
            return Assembly.Load(assemblyName);
        }
    }

  好了,现在我们回到Registry.cs文件当中的Scan方法,下面这句话的意思就是如果当前实例Registry所引用的程序集和Registry所引用的程序集一致的判断:

GetType().GetTypeInfo().Assembly == typeof(Registry).GetTypeInfo().Assembly

  

//Scanner数量+1
scanner.Description = "Scanner #" + (Scanners.Count + 1);

//某个类别的Scanner加1
scanner.Description = "{0} Scanner #{1}".ToFormat(GetType().Name, (Scanners.Count + 1));

  注意以下Scan方法里面的action(xxx),xxx这里指的是方法名,并且是无返回值的方法(基础知识,温习一下),然后再把当前的scanner添加进全局的Registry的实例当中:

        internal readonly IList<AssemblyScanner> Scanners = new List<AssemblyScanner>(); 

  好了,这篇文章很水很水,但是我还是决定放首页,啦啦啦~~~

posted @ 2015-12-22 00:28  KMSFan  阅读(433)  评论(1编辑  收藏  举报
document.getElementById("homeTopTitle").innerText="ღKawaii";