/// <summary>
        ///     初始化插件。
        ///     请勿在此方法调用<see cref="M:FxEcis.T0000.IoC.EcisContainer.Resolve(System.Type)" />、<see cref="M:FxEcis.T0000.IoC.EcisContainer.ResolveAll(System.Type)" />方法,这会导致容器锁定,后续的注册会失败。
        ///     如需要解析类型,应该使用<see cref="P:FxEcis.T0000.IoC.EcisContainer.EventAggregator" />获取<see cref="T:FxEcis.T0000.IoC.ContainerEndInitEvent" />事件,然后在事件触发后解析
        /// </summary>
        /// <param name="container">默认的<see cref="T:FxEcis.T0000.IoC.EcisContainer" />容器</param>
        public override void InitPlugin(EcisContainer container)
        {
            //这样是注册一个类型,每次解析时都会新建一个实例对象
            //container.Register<ISaveTriageInfo,SaveTriageInfo1>();

            //这样是注册到集合
            container.RegisterCollection <ISaveTriageInfo>(new [] { typeof(SaveTriageInfo1), typeof(SaveTriageInfo2) });

            //SaveTriageInfo2构造参数内包含了ILogger
            //这里注册后,解析SaveTriageInfo2时,会自动传入Logger的实例
            //注册不分先后顺序
            container.Register <ILogger, Logger>();

            //注册到单个实现和注册到集合并不冲突。具体的解析,可看ResolveIoCPlugin
            //但是一般不会这样用,程序设计时,应该就确定一个接口能有多少个实现。
            //比如说,一个分诊保存的逻辑,只能有一个。但是,病历插入内容模块的接口,可以有插入医嘱、插入检查等等的实现。

            //这样注册,是单例模式,容器只会创建一个实例对象,然后将其缓存,每次解析都会返回这个实例。
            //container.RegisterSingleton<ISaveTriageInfo, SaveTriageInfo1>();

            //这样注册,也是单例模式,这样是自己创建一个实例,这种情况,适用于,构造函数中需要传入int,string等简单类型等情况
            //如果是构造函数是可变参数,也需要使用这种方式注册。IoC的内部实现不允许构造函数是可变参数。
            //container.RegisterInstance<ISaveTriageInfo>(new SaveTriageInfo1());

            //这样注册,会将上面的注册给替换掉,SaveTriageInfo1被替换成SaveTriageInfo2。
            //container.Register<ISaveTriageInfo, SaveTriageInfo2>();


            //高级注册说明,EcisContainer是其它IoC框架的封装
            //如果以上注册方法无法满足需求(这种情况应该很少遇到)
            //目前内部使用的是SimpleInjector,可查看其文档:https://simpleinjector.readthedocs.io/en/latest/quickstart.html
            //内部容器在:
            //container.Container
        }
 private static void WhenEndInit(EcisContainer container)
 {
     //在容器初始化完毕后再发送事件,防止在注册之前就已经触发事件了
     //这里是模拟发布事件
     //正常情况下,发送事件应该在我们程序内部发送,然后插件这里只做订阅操作。
     container.EventAggregator.GetEvent <TestEvent>().Publish("测试事件已发送");
 }
Example #3
0
 /// <summary>
 ///     初始化插件。
 ///     请勿在此方法调用<see cref="M:FxEcis.T0000.IoC.EcisContainer.Resolve(System.Type)" />、<see cref="M:FxEcis.T0000.IoC.EcisContainer.ResolveAll(System.Type)" />方法,这会导致容器锁定,后续的注册会失败。
 ///     如需要解析类型,应该使用<see cref="P:FxEcis.T0000.IoC.EcisContainer.EventAggregator" />获取<see cref="T:FxEcis.T0000.IoC.ContainerEndInitEvent" />事件,然后在事件触发后解析
 /// </summary>
 /// <param name="container">默认的<see cref="T:FxEcis.T0000.IoC.EcisContainer" />容器</param>
 public override void InitPlugin(EcisContainer container)
 {
     //一般来说,插件这里是不需要解析实例的,即调用 EcisContainer.Resolve 方法。因为很少用得到。
     //这里只是为了显示如何在程序内解析实例的。
     //请勿直接在这里调用 EcisContainer.Resolve 方法,会导致内部容器被锁定。
     //插件的载入顺序不是固定的,如果这里直接解析了类型,如果下一个插件还需要注册类型,将导致程序直接抛出异常。
     //所以这里需要订阅 ContainerEndInitEvent 事件(容器已初始化完毕事件),然后再进行解析操作。
     container.EventAggregator.GetEvent <ContainerEndInitEvent>().Subscribe(ResolveWhenEndInit);
 }
        /// <summary>初始化插件</summary>
        /// <param name="container">默认的<see cref="T:FxEcis.T0000.IoC.EcisContainer" />容器</param>
        public override void InitPlugin(EcisContainer container)
        {
            //获取到TestEvent事件
            var @event = container.EventAggregator.GetEvent <TestEvent>();

            //订阅事件。
            //如果在插件中,Subscribe注册的方法,需要是静态方法,防止订阅被回收。
            //或者调用 Subscribe 方法时,keepSubscriberReferenceAlive 参数改成 true。
            //或者用其它方式自己管理该方法,如静态类等来保持该方法不会被.net的垃圾回收器回收。
            //订阅事件的方法,有多个重载,可自己查看。
            @event.Subscribe(Test, ThreadOption.PublisherThread);

            //订阅可以进行过滤。
            //比如说,这里判断事件的传参不是空值的情况下,才调用Test方法。
            @event.Subscribe(Test, ThreadOption.PublisherThread,
                             true,
                             s => !string.IsNullOrWhiteSpace(s));
        }
Example #5
0
        /// <summary>初始化插件</summary>
        /// <param name="container">默认的<see cref="T:FxEcis.T0000.IoC.EcisContainer" />容器</param>
        public override void InitPlugin(EcisContainer container)
        {
            //这里用的是Harmony
            //使用的功能也会是相对来说比较简单的
            //项目说明是 https://github.com/pardeike/Harmony/wiki
            //有相关问题,可访问以上URL查看详细的文档
            var harmony = HarmonyInstance.Create("Ecis.Pacth");

            //这样是最方便注册补丁的方法。
            //但是这样也一样需要在补丁的类增加 HarmonyPatch 等属性
            //但是这样会存在一个问题,如果这个DLL有两个插件,都需要使用这个功能(两个插件都调用了该方法),可能会导致补丁多次注册,从而执行了多次。
            //harmony.PatchAll(Assembly.GetExecutingAssembly());

            //以下写法比较麻烦,但是会更加稳定,不会影响到其它插件的运行
            var original   = AccessTools.Method(typeof(PatientRegisterStrategy), "PatientRegister");
            var prefix     = new HarmonyMethod(typeof(PatchPatientRegisterStaticMethod), "Prefix");
            var postfix    = new HarmonyMethod(typeof(PatchPatientRegisterStaticMethod), "Postfix");
            var transpiler = new HarmonyMethod(typeof(PatchPatientRegisterStaticMethod), "Transpiler");

            harmony.Patch(original, prefix, postfix, transpiler);
        }
Example #6
0
        private static void ResolveWhenEndInit(EcisContainer container)
        {
            //因为容器都已经初始化了,全部的插件也都载入完成了。这里已经可以解析实例。

            //用于判断有没有注册这个类型
            container.IsRegister <ISaveTriageInfo>();
            container.IsRegisterCollection <ISaveTriageInfo>();

            //这里获取到的是 SaveTriageInfo1
            //因为RegisterIoCPlugin.cs中,调用的是
            //  container.Register<ISaveTriageInfo,SaveTriageInfo1>();
            //如果没注册过该类型,直接解析的话会抛出异常。
            var saveTriageInfo = container.Resolve <ISaveTriageInfo>();

            saveTriageInfo.Save(null);

            //这里获取到的是 SaveTriageInfo1 ,SaveTriageInfo2
            //因为RegisterIoCPlugin.cs中,调用的是
            //  container.RegisterCollection<ISaveTriageInfo>(new []{typeof(SaveTriageInfo1),typeof(SaveTriageInfo2) });
            var saveTriageInfos = container.ResolveAll <ISaveTriageInfo>();

            foreach (var triageInfo in saveTriageInfos)
            {
                triageInfo.Save(null);
            }

            //这样也可以解析集合。
            var saveTriageInfos2 = container.Resolve <IEnumerable <ISaveTriageInfo> >().ToList();

            foreach (var triageInfo in saveTriageInfos2)
            {
                triageInfo.Save(null);
            }

            //注意,如果只调用了container.Register来注册,只能用container.Resolve来解析。
            //如果只调用了container.RegisterCollection来注册,只能用container.ResolveAll或Resolve<IEnumerable<>>来解析。
            //否则解析不到数据,并且会抛出异常。
        }
 /// <summary>初始化插件</summary>
 /// <param name="container">默认的<see cref="T:FxEcis.T0000.IoC.EcisContainer" />容器</param>
 public override void InitPlugin(EcisContainer container)
 {
     container.EventAggregator.GetEvent <ContainerEndInitEvent>().Subscribe(WhenEndInit);
 }
Example #8
0
 /// <summary>
 ///     初始化插件。
 ///     请勿在此方法调用<see cref="M:FxEcis.T0000.IoC.EcisContainer.Resolve(System.Type)" />、<see cref="M:FxEcis.T0000.IoC.EcisContainer.ResolveAll(System.Type)" />方法,这会导致容器锁定,后续的注册会失败。
 ///     如需要解析类型,应该使用<see cref="P:FxEcis.T0000.IoC.EcisContainer.EventAggregator" />获取<see cref="T:FxEcis.T0000.IoC.ContainerEndInitEvent" />事件,然后在事件触发后解析
 /// </summary>
 /// <param name="container">默认的<see cref="T:FxEcis.T0000.IoC.EcisContainer" />容器</param>
 public override void InitPlugin(EcisContainer container)
 {
 }