• 服务层的设计


    服务层的设计

    服务层代码

    首先我先放出2个主要类的代码再分别讲解

    接口

    实现

    查询实体

    上一节提到Specification实现查询功能,主要实现Where功能, 但是查询还需要数据承载,查询实体就是数据的承载,其中数据到 表达式或者sql的拼接就是在GetFilter中实现的,这里要注意写法特别是 expression=expression.And(xxx).一定要赋值给自己。SearchBase只是一个泛型限制里面暂时没有任何实现

    以下是一个GetFilter实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    protected override ISpecification<PrivateLesson> GetFilter(LessonSearch search)
    {
        var expression = (Expression<Func<PrivateLesson, bool>>)(item => true);
        if (search == null)
            return base.GetFilter(null);
        if (search.StartTime != default(DateTime))
            expression = expression.And(item => item.StartTime > search.StartTime);
     
        if (search.EndTime != default(DateTime))
            expression = expression.And(item => item.StartTime < search.EndTime);
     
        if (!string.IsNullOrWhiteSpace(search.Text))
            expression =
                expression.And(item => item.Name.Contains(search.Text) || item.Coach.Name.Contains(search.Text));
     
        return new DirectSpecification<PrivateLesson>(expression);
    }

    排序实体

    等同于查询实体,排序实体也是排序功能的数据承载,OrderBase只是一个泛型限制,里面暂时没有任何实现

    泛型维度的缩放


    对于上面排序和查询的功能并不是一定都需要,所以做了维度缩放,可以从三种
    维度去使用Crud的服务.
    对于服务的实现上加入了模型实体(也就是和数据库映射的模型),这么做的好处是
    使用接口的人无需知道数据库怎么存放表怎么映射,接口和实现分离。

    Mapper

    我们选用EmitMapper作为Entity和DTO的映射,目前来看这个性能是除了直接赋值
    之外性能最好的了,网上有很多对比文章请自行参考。当然如果你不习惯也可以
    换一种实现

    这里代码参考NLayerApp中Mapper的设计,略作修改

    注意这里配置文件采用Dynamic的方式可以让简单使用的地方不需要引用EmitMapper,

    除非是要做一些扩展

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    namespace Coralcode.Framework.Mapper
    {
        public class DataMapperProvider
        {
            public static IDataMapper  Mapper
            {
                get return new EmitmapperDataMapper(); }
            }
        }
    }
     
     
     
    namespace Coralcode.Framework.Mapper
    {
        public interface IDataMapper
        {
            TTarget Convert<TSource, TTarget>(TSource source)
                where TTarget : classnew()
                where TSource : class;
     
            TTarget Convert<TSource, TTarget>(TSource source, TTarget target)
                where TTarget : class
                where TSource : class;
     
            /// <summary>
            /// 带配置文件的转换
            /// </summary>
            /// <typeparam name="TSource"></typeparam>
            /// <typeparam name="TTarget"></typeparam>
            /// <param name="source"></param>
            /// <param name="target"></param>
            /// <param name="config">配置文件</param>
            /// <returns></returns>
            TTarget Convert<TSource, TTarget>(TSource source, TTarget target, dynamic config)
                where TTarget : class
                where TSource : class;
     
            /// <summary>
            /// 带配置文件的转换
            /// </summary>
            /// <typeparam name="TSource"></typeparam>
            /// <typeparam name="TTarget"></typeparam>
            /// <param name="source"></param>
            /// <param name="config">配置文件</param>
            /// <returns></returns>
            TTarget Convert<TSource, TTarget>(TSource source, dynamic config)
                where TTarget : classnew()
                where TSource : class;
        }
    }
     
    using EmitMapper;
    using EmitMapper.MappingConfiguration;
     
    namespace Coralcode.Framework.Mapper
    {
        public class EmitmapperDataMapper
            : IDataMapper
        {
            #region ITypeAdapter Members
     
            public TTarget Convert<TSource, TTarget>(TSource source)
                where TSource : class
                where TTarget : classnew()
            {
                ObjectsMapper<TSource, TTarget> mapper =
                    ObjectMapperManager.DefaultInstance.GetMapper<TSource, TTarget>(new DefaultMapConfig());
                return mapper.Map(source);
            }
     
            public TTarget Convert<TSource, TTarget>(TSource source, TTarget target)
                where TTarget : class
                where TSource : class
            {
                ObjectsMapper<TSource, TTarget> mapper =
                    ObjectMapperManager.DefaultInstance.GetMapper<TSource, TTarget>(new DefaultMapConfig());
                return mapper.Map(source, target);
            }
     
     
            public TTarget Convert<TSource, TTarget>(TSource source, TTarget target, dynamic config)
                where TTarget : class
                where TSource : class
            {
                ObjectsMapper<TSource, TTarget> mapper =
                    ObjectMapperManager.DefaultInstance.GetMapper<TSource, TTarget>((DefaultMapConfig)config);
                return mapper.Map(source, target);
            }
     
     
            public TTarget Convert<TSource, TTarget>(TSource source, dynamic config)
                where TTarget : classnew()
                where TSource : class
            {
                ObjectsMapper<TSource, TTarget> mapper =
                    ObjectMapperManager.DefaultInstance.GetMapper<TSource, TTarget>(config);
                return mapper.Map(source);
            }
     
            #endregion
        }
    }

    EF更新机制

    EF更新这也是我经常使用的一个面试题,很多人会回答直接由Update方法可以调用
    实际上ef是通过代理对象并且实现INotifyChange接口来监听属性的改变。
    EF更新的时候不能修改主键的值,所以我这里做了忽略。其他属性全部更新,
    当然如果涉及到具体业务比如修改账号或者金额之类的修改,最好是扩展服务实现
    不要用这个服务中自带的更新方法,直接使用Repository去更新

    Attribute注入配置化

    这里我使用Attribute做Ioc配置,其中生命周期的枚举参考unity框架的设计,
    具体怎么使用可以参考网上的文章。
    实现机制是在一个用启动的时候扫描程序集有这个标记的类型,然后读出
    RegisterType做注册,并且支持多注册

    UnityService的代码

     注意这里Register方法最后一个参数用dynamic,这样使用的地方就可以不依赖于Unity,

    其中包含了Aop和几个设计技巧,有问题的可以留言我再做解答

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    428
    429
    430
    431
    432
    433
    434
    435
    436
    using System;
    using System.Collections.Concurrent;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Reflection;
    using Coralcode.Framework.Extensions;
    using Coralcode.Framework.Reflection;
    using Microsoft.Practices.Unity;
    using Microsoft.Practices.Unity.InterceptionExtension;
     
    namespace Coralcode.Framework.Aspect.Unity
    {
        /// <summary>
        /// IOC容器
        /// </summary>
        public class UnityService
        {
     
            static UnityService()
            {
                //注册标记
                Current = new UnityContainer();
                Current.AddNewExtension<Interception>();
     
                var currentType = typeof(UnityService);
                var containers = new List<dynamic>();
     
     
                //模块初始化
                containers.ForEach(item => item.Regist());
                //模块启动
                containers.ForEach(item => item.RegistComplete());
                MetaDataManager.Type.GetAllTypes().ForEach(item =>
                {
                    if (item == null)
                        return;
     
                    var registers = item.GetCustomAttributes<InjectAttribute>().ToList();
                    if (registers.Count == 0)
                        return;
                    registers.ForEach(register =>
                    {
                        if (register.RegisterType != null)
                            RegisterType(register.Name, register.RegisterType, item, GetLifetimeManager(register.LifetimeManagerType), GetInjectionMembers(register.AopType, item));
                        else
                            RegisterType(register.Name, item, GetLifetimeManager(register.LifetimeManagerType), GetInjectionMembers(register.AopType, item));
                    });
                });
            }
     
            #region 属性
     
            /// <summary>
            ///     Get the current configured container
            /// </summary>
            /// <returns>Configured container</returns>
            private static IUnityContainer Current { getset; }
     
     
            #endregion
     
     
            /// <summary>
            /// 在当前模块中注册接口的实现
            /// </summary>
            protected virtual void Regist()
            {
            }
            /// <summary>
            /// 在当前模块中注册应用程序启动事件
            /// </summary>
            protected virtual void RegistComplete()
            {
            }
     
            #region 注册相关的方法
            /// <summary>
            /// 获取生命周期
            /// </summary>
            /// <param name="lifetimeManagerType"></param>
            /// <returns></returns>
            public static LifetimeManager GetLifetimeManager(LifetimeManagerType lifetimeManagerType)
            {
                switch (lifetimeManagerType)
                {
                    case LifetimeManagerType.Transient:
                        return new TransientLifetimeManager();
                    case LifetimeManagerType.ContainerControlled:
                        return new ContainerControlledLifetimeManager();
                    case LifetimeManagerType.Hierarchica:
                        return new HierarchicalLifetimeManager();
                    case LifetimeManagerType.Externally:
                        return new ExternallyControlledLifetimeManager();
                    case LifetimeManagerType.PerThread:
                        return new PerThreadLifetimeManager();
                    case LifetimeManagerType.PerResolve:
                        return new PerResolveLifetimeManager();
                    default:
                        return new TransientLifetimeManager();
                }
            }
     
            /// <summary>
            /// 注入aop方法
            /// </summary>
            /// <param name="aopType"></param>
            /// <param name="type"></param>
            /// <returns></returns>
            public static InjectionMember[] GetInjectionMembers(AopType aopType, Type type)
            {
                var members = new List<InjectionMember>();
                switch (aopType)
                {
                    case AopType.VirtualMethodInterceptor:
                        members.Add(new Interceptor<VirtualMethodInterceptor>());
                        break;
                    case AopType.InterfaceInterceptor:
                        members.Add(new Interceptor<InterfaceInterceptor>());
                        break;
                    case AopType.TransparentProxyInterceptor:
                        members.Add(new Interceptor<TransparentProxyInterceptor>());
                        break;
                }
                members.AddRange(type.GetCustomAttributes()
                       .Where(item => item.GetType().IsSubclassOf(typeof(UnityAopAttribute)))
                       .Cast<UnityAopAttribute>()
                       .Select(item => new InterceptionBehavior(item)));
                return members.ToArray();
     
            }
            #endregion
     
            /// <summary>
            ///     注册泛型类型
            /// </summary>
            /// <param name="injectionMembers">构造函数参数</param>
            public static void Register<TTarget, TSource>(params dynamic[] injectionMembers) where TSource : TTarget
            {
                RegisterType<TTarget, TSource>("",injectionMembers);
            }
     
     
     
            /// <summary>
            ///     注册泛型类型
            /// </summary>
            /// <param name="name"></param>
            /// <param name="injectionMembers">构造函数参数</param>
            public static void RegisterType<TTarget, TSource>(string name, params dynamic[] injectionMembers) where TSource : TTarget
            {
                var members = new List<InjectionMember>();
                LinqExtensions.ForEach(injectionMembers, item =>
                {
                    if (item is InjectionMember)
                        members.Add(item);
                    if (item is InjectionMember[])
                        members.AddRange(item);
                    else if (item is ConstructorParameter)
                        members.Add(new InjectionConstructor(item.Value));
                    else if (item is ConstructorParameter[])
                        members.AddRange((item as ConstructorParameter[]).Select(data => new InjectionConstructor(data.Value)));
                });
     
                var lifetimeManager = injectionMembers.OfType<LifetimeManager>().FirstOrDefault();
                if (string.IsNullOrEmpty(name))
                {
                    if (lifetimeManager == null && injectionMembers == null)
                        Current.RegisterType<TTarget, TSource>();
     
                    else if (lifetimeManager == null)
                        Current.RegisterType<TTarget, TSource>(members.ToArray());
                    else if (injectionMembers == null)
                        Current.RegisterType<TTarget, TSource>(lifetimeManager);
                    else
                        Current.RegisterType<TTarget, TSource>(lifetimeManager, members.ToArray());
     
                }
                else
                {
                    if (lifetimeManager == null && injectionMembers == null)
                        Current.RegisterType<TTarget, TSource>(name);
     
                    else if (lifetimeManager == null)
                        Current.RegisterType<TTarget, TSource>(name, members.ToArray());
                    else if (injectionMembers == null)
                        Current.RegisterType<TTarget, TSource>(name, lifetimeManager);
                    else
                        Current.RegisterType<TTarget, TSource>(name, lifetimeManager, members.ToArray());
     
                }
            }
     
     
            /// <summary>
            /// 注册类型
            /// </summary>
            /// <param name="source"></param>
            /// <param name="target"></param>
            /// <param name="lifetimeManager"></param>
            /// <param name="injectionMembers"></param>
            public static void RegisterType(string name, Type target, Type source, params dynamic[] injectionMembers)
            {
                var members = new List<InjectionMember>();
                LinqExtensions.ForEach(injectionMembers, item =>
                {
                    if (item is InjectionMember)
                        members.Add(item);
                    if (item is InjectionMember[])
                        members.AddRange(item);
                    else if (item is ConstructorParameter)
                        members.Add(new InjectionConstructor(item.Value));
                    else if (item is ConstructorParameter[])
                        members.AddRange((item as ConstructorParameter[]).Select(data => new InjectionConstructor(data.Value)));
                });
                var lifetimeManager = injectionMembers.OfType<LifetimeManager>().FirstOrDefault();
     
     
                if (string.IsNullOrEmpty(name))
                {
     
                    if (lifetimeManager == null && injectionMembers == null)
                        Current.RegisterType(target, source);
                    else if (lifetimeManager == null)
                        Current.RegisterType(target, source, members.ToArray());
                    else if (injectionMembers == null)
                        Current.RegisterType(target, source, lifetimeManager);
                    else
                        Current.RegisterType(target, source, lifetimeManager, members.ToArray());
     
                }
                else
                {
                    if (lifetimeManager == null && injectionMembers == null)
                        Current.RegisterType(target, source, name);
                    else if (lifetimeManager == null)
                        Current.RegisterType(target, source, name, members.ToArray());
                    else if (injectionMembers == null)
                        Current.RegisterType(target, source, name, lifetimeManager);
                    else
                        Current.RegisterType(target, source, name, lifetimeManager, members.ToArray());
                }
            }
     
            /// <summary>
            /// 注册类型
            /// </summary>
            /// <param name="source"></param>
            /// <param name="target"></param>
            /// <param name="lifetimeManager"></param>
            /// <param name="injectionMembers"></param>
            public static void RegisterType(Type target, Type source, params dynamic[] injectionMembers)
            {
                var members = new List<InjectionMember>();
                LinqExtensions.ForEach(injectionMembers, item =>
                {
                    if (item is InjectionMember)
                        members.Add(item);
                    if (item is InjectionMember[])
                        members.AddRange(item);
                    else if (item is ConstructorParameter)
                        members.Add(new InjectionConstructor(item.Value));
                    else if (item is ConstructorParameter[])
                        members.AddRange((item as ConstructorParameter[]).Select(data => new InjectionConstructor(data.Value)));
                });
                var lifetimeManager = injectionMembers.OfType<LifetimeManager>().FirstOrDefault();
     
     
     
     
                if (lifetimeManager == null && injectionMembers == null)
                    Current.RegisterType(target, source);
                else if (lifetimeManager == null)
                    Current.RegisterType(target, source, members.ToArray());
                else if (injectionMembers == null)
                    Current.RegisterType(target, source, lifetimeManager);
                else
                    Current.RegisterType(target, source, lifetimeManager, members.ToArray());
            }
     
            /// <summary>
            /// 注册类型
            /// </summary>
            /// <param name="injectionMembers"></param>
            public static void RegisterType(Type type, params dynamic[] injectionMembers)
            {
                var members = new List<InjectionMember>();
                LinqExtensions.ForEach(injectionMembers, item =>
                {
                    if (item is InjectionMember)
                        members.Add(item);
                    if (item is InjectionMember[])
                        members.AddRange(item);
                    else if (item is ConstructorParameter)
                        members.Add(new InjectionConstructor(item.Value));
                    else if (item is ConstructorParameter[])
                        members.AddRange((item as ConstructorParameter[]).Select(data => new InjectionConstructor(data.Value)));
                });
                var lifetimeManager = injectionMembers.OfType<LifetimeManager>().FirstOrDefault();
     
                if (lifetimeManager == null && injectionMembers == null)
                    Current.RegisterType(type);
                else if (lifetimeManager == null)
                    Current.RegisterType(type, members.ToArray());
                else if (injectionMembers == null)
                    Current.RegisterType(type, lifetimeManager);
                else
                    Current.RegisterType(type, lifetimeManager, members.ToArray());
            }
     
            /// <summary>
            /// 注册类型
            /// </summary>
            /// <param name="type"></param>
            /// <param name="injectionMembers"></param>
            /// <param name="name"></param>
            public static void RegisterType(string name, Type type, params dynamic[] injectionMembers)
            {
                var members = new List<InjectionMember>();
                LinqExtensions.ForEach(injectionMembers, item =>
                {
                    if (item is InjectionMember)
                        members.Add(item);
                    if (item is InjectionMember[])
                        members.AddRange(item);
                    else if (item is ConstructorParameter)
                        members.Add(new InjectionConstructor(item.Value));
                    else if (item is ConstructorParameter[])
                        members.AddRange((item as ConstructorParameter[]).Select(data => new InjectionConstructor(data.Value)));
                });
                var lifetimeManager = injectionMembers.OfType<LifetimeManager>().FirstOrDefault();
     
                if (string.IsNullOrEmpty(name))
                {
                    if (lifetimeManager == null && injectionMembers == null)
                        Current.RegisterType(type);
                    else if (lifetimeManager == null)
                        Current.RegisterType(type, members.ToArray());
                    else if (injectionMembers == null)
                        Current.RegisterType(type, lifetimeManager);
                    else
                        Current.RegisterType(type, lifetimeManager, members.ToArray());
                }
                else
                {
                    if (lifetimeManager == null && injectionMembers == null)
                        Current.RegisterType(type, name);
                    else if (lifetimeManager == null)
                        Current.RegisterType(type, name, members.ToArray());
                    else if (injectionMembers == null)
                        Current.RegisterType(type, name, lifetimeManager);
                    else
                        Current.RegisterType(type, name, lifetimeManager, members.ToArray());
                }
            }
     
     
     
            /// <summary>
            /// 创建实例
            /// </summary>
            /// <param name="source"></param>
            /// <returns></returns>
            public static object Resolve(Type source)
            {
                return Current.Resolve(source);
            }
     
            private static ConcurrentDictionary<string, Action<dynamic>> _handles = new ConcurrentDictionary<string, Action<dynamic>>();
     
            /// <summary>
            /// 当创建新实例时触发
            /// </summary>
            /// <param name="handler"></param>
            /// <returns></returns>
            public void OnCreation<T>(Action<T> handler)
            {
                _handles.TryAdd(typeof(T).FullName, item => handler(item.Data));
            }
     
            public static bool HasRegistered(Type type)
            {
                return Current.IsRegistered(type);
            }
     
            /// <summary>
            /// 创建泛型实例
            /// </summary>
            /// <returns></returns>
            public static T Resolve<T>()
            {
                var result = Current.Resolve<T>();
                Action<dynamic> handler;
                if (_handles.TryGetValue(typeof(T).FullName, out handler))
                {
                    handler(new EventArgs<T>(result));
                }
                return result;
            }
     
            /// <summary>
            /// 创建泛型实例
            /// </summary>
            /// <returns></returns>
            public static T Resolve<T>(string name)
            {
                return Current.Resolve<T>(name);
            }
     
            /// <summary>
            /// 创建泛型实例集合
            /// </summary>
            /// <returns></returns>
            public static T[] ResolveAll<T>()
            {
                var serviceImpls = Current.ResolveAll<T>();
                List<T> proxiedServiceImpls = new List<T>();
                foreach (var serviceImpl in serviceImpls)
                {
                    Action<dynamic> handler;
                    if (_handles.TryGetValue(typeof(T).FullName, out handler))
                    {
                        handler(new EventArgs<T>(serviceImpl));
                    }
                    proxiedServiceImpls.Add(serviceImpl);
                }
     
                return proxiedServiceImpls.ToArray();
            }
     
            public static void Release(object obj)
            {
                Current.Teardown(obj);
            }
        }
    }

     辅助类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    using System;
     
    namespace Coralcode.Framework.Aspect
    {
        [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
        public class InjectAttribute : Attribute
        {
            /// <summary>
            /// 注册的名字
            /// </summary>
            public string Name { getset; }
     
            /// <summary>
            /// 依赖注入的类型
            /// </summary>
            public Type RegisterType { getset; }
     
            /// <summary>
            /// 注册条件
            /// </summary>
            public RegisterCondition Condition { getset; }
     
            /// <summary>
            /// aop类型
            /// </summary>
            public AopType AopType { getset; }
     
            /// <summary>
            /// 生命周期类型
            /// </summary>
            public LifetimeManagerType LifetimeManagerType { getset; }
        }
     
        [Flags]
        public enum RegisterCondition
        {
            /// <summary>
            /// 是否必须
            /// </summary>
            IsRequire = 1,
        }
     
        /// <summary>
        /// 拦截类型
        /// </summary>
        public enum AopType
        {
            /// <summary>
            /// 不拦截
            /// </summary>
            None,
            /// <summary>
            /// 虚方法拦截
            /// </summary>
            VirtualMethodInterceptor,
            /// <summary>
            /// 接口拦截
            /// </summary>
            InterfaceInterceptor,
            /// <summary>
            /// 动态代理拦截
            /// </summary>
            TransparentProxyInterceptor,
            //这里可以添加自定义
        }
     
        public enum LifetimeManagerType
        {
            /// <summary>
            /// 每次通过Resolve或ResolveAll调用对象的时候都会重新创建一个新的对象。
            /// </summary>
            Transient,
            /// <summary>
            /// 容器控制生命周期管理,这个生命周期管理器是RegisterInstance默认使用的生命周期管理器,也就是单件实例
            /// </summary>
            ContainerControlled,
            /// <summary>
            /// 分层生命周期管理器,这个管理器类似于ContainerControlledLifetimeManager,
            /// 也是由UnityContainer来管理,也就是单件实例。
            /// 不过与ContainerControlledLifetimeManager不 同的是,
            /// 这个生命周期管理器是分层的,
            /// 因为Unity的容器时可以嵌套的,所以这个生命周期管理器就是针对这种情况,
            /// 当使用了这种生命周期管理器,
            /// 父容器 和子容器所维护的对象的生命周期是由各自的容器来管理
            /// </summary>
            Hierarchica,
            /// <summary>
            /// 外部控制生命周期管理器,这个 生命周期管理允许你使用RegisterType和RegisterInstance来注册对象之间的关系,
            /// 但是其只会对对象保留一个弱引用,
            /// 其生命周期 交由外部控制,也就是意味着你可以将这个对象缓存或者销毁而不用在意UnityContainer,
            /// 而当其他地方没有强引用这个对象时,其会被GC给销毁 掉。
            /// </summary>
            Externally,
            /// <summary>
            /// 每线程生命周期管理器,就是保证每个线程返回同一实例
            /// </summary>
            PerThread,
            /// <summary>
            /// 其类似于 TransientLifetimeManager,但是其不同在于,
            /// 如果应用了这种生命周期管理器,
            /// 则在第一调用的时候会创建一个新的对象,
            /// 而再次通过 循环引用访问到的时候就会返回先前创建的对象实例(单件实例),
            /// </summary>
            PerResolve,
        }<br>}

    Aop辅助类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    using System;
    using Microsoft.Practices.Unity;
    using Microsoft.Practices.Unity.InterceptionExtension;
     
    namespace Coralcode.Framework.Aspect.Unity
    {
        [AttributeUsage(AttributeTargets.Method|AttributeTargets.Class|AttributeTargets.Interface)]
        public abstract class UnityAopAttribute : HandlerAttribute, ICallHandler, IInterceptionBehavior
        {
            public override ICallHandler CreateHandler(IUnityContainer container)
            {
                return this;
            }
     
            public System.Collections.Generic.IEnumerable<Type> GetRequiredInterfaces()
            {
                return Type.EmptyTypes;
            }
     
            /// <summary>
            /// 调用之后的实现逻辑
            /// </summary>
            /// <param name="input"></param>
            /// <returns></returns>
            protected virtual void OnAfter(IMethodInvocation input)
            {
                 
            }
     
     
            /// <summary>
            /// 调用之前的实现逻辑
            /// </summary>
            /// <param name="input"></param>
            /// <returns></returns>
            protected virtual void OnBefore(IMethodInvocation input)
            {
                 
            }
     
            /// <summary>
            /// 调用出现异常的实现逻辑
            /// </summary>
            /// <param name="input"></param>
            /// <returns></returns>
            protected virtual void OnException(IMethodInvocation input, Exception ex)
            {
                throw ex;
            }
     
            /// <summary>
            /// 接口注入时候的拦截方法
            /// </summary>
            /// <param name="input"></param>
            /// <param name="nextMethod"></param>
            /// <returns></returns>
            public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate nextMethod)
            {
                OnBefore(input);
                IMethodReturn result = null;
                try
                {
                    result = nextMethod()(input, nextMethod);
                }
                catch (Exception ex)
                {
                    OnException(input, ex);
                }
                OnAfter(input);
                return result;
            }
     
            /// <summary>
            /// 虚方法注入的拦截方法
            /// </summary>
            /// <param name="input"></param>
            /// <param name="nextMethod"></param>
            /// <returns></returns>
            public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate nextMethod)
            {
                OnBefore(input);
                IMethodReturn result=null;
                try
                {
                   result = nextMethod()(input, nextMethod);
                }
                catch (Exception ex)
                {
                    OnException(input, ex);
                }
                OnAfter(input);
                return result;
            }
     
            public bool WillExecute
            {
                get return true; }
            }
        }
    }

    得益于Mvc的filter,实际项目中很少用到AOP,如果需要使用继承自这个类并标记在需要拦截的地方即可

    EventBus

    这里EventBus参考Abp和ApWorks的设计,这个发送的不算领域事件,是应用层
    事件,在我项目中Event主要使用在三个地方
    >*  统计模块预定事件以后可以根据设计好的查询需求去存放数据
        这样会比原来从原始表中load数据快很多.
    >*  在比如菜单中可以注册类型的事件实现菜单的动态修改。
        这个会在做界面层的时候提到
    >*  缓存数据的即时更新

     
  • 相关阅读:
    “error LNK1169: 找到一个或多个多重定义的符号”的解决方法(转载)
    std::ostringstream 转std::string
    【转载】红外感应模块+蜂鸣器实现简易报警
    分割字符串使用空格
    优秀程序员的 18 大法则【转载】
    解决win10 iot VS编程出现的无法引用错误
    [转载] 程序员如何成功追到女神?
    win8/win10/win2012r2 存储池 冗余分析
    [转载][NAS] 使用win8的“存储池”功能~
    mySQL中删除unique key的语法 (删除某个字段的唯一性)
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/5649335.html
Copyright © 2020-2023  润新知