服务层的设计

服务层的设计

服务层代码

首先我先放出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数据快很多.
>*  在比如菜单中可以注册类型的事件实现菜单的动态修改。
    这个会在做界面层的时候提到
>*  缓存数据的即时更新

分类: CRUD全栈式编程架构

时间: 2024-10-16 10:17:00

服务层的设计的相关文章

CRUD全栈式编程架构之服务层的设计

服务层代码 首先我先放出2个主要类的代码再分别讲解 接口 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Coralcode.Framework.Models; using Coralcode.Framework.Page; namespace Coralcode.Framework.Services

面向对象的应用服务层设计

前言 N层的应用软件系统,由于其众多的优点,已经成为典型的软件系统架构,也已经为广大开发人员所熟知.在一个典型的三层应用软件系统中,应用系统通常被划分成以下三个层次:数据库层.应用服务层和用户界面层.如下图所示: 其中,应用服务层集中了系统的业务逻辑的处理,因此,可以说是应用软件系统中的核心部分.软件系统的健壮性.灵活性.可重用性.可升级性和可维护性,在很大程度上取决于应用服务层的设计.因此,如何构建一个良好架构的应用服务层,是应用软件开发者需要着重解决的问题. 为了使应用服务层的设计达到最好的

系统架构师-基础到企业应用架构-服务层

一.上章回顾 上篇我们主要讲解了系统架构中的四种架构模式,并且分析了四种架构模式的实现及应用场景,那么先来回顾下架构中的业务逻辑层的使用及总结.  如果大家对图中讲述的内容不明白或者说是不深入那么可以参考上篇讲 解的内容:系统架构师-基础到企业应用架构-业务逻辑层. 二.摘要 本文将已架构的方式去分析分层结构中的服务层的设计,如何设计出来满足我们说的业务需求及设计规范的服务层将是我们的目标,可能我想大家在项目架构的 过程中可能有些同仁,没有用到该层,或者说是采用的是常用的分层结构的设计,而没有把

C++服务器设计(四):超时管理机制设计

前四章介绍了系统层的设计,从这一章开始进入服务层的设计. 连接断开 在常见的服务器场景中,客户端断开连接的方式为被动关闭.即作为客户端请求完服务器的服务后,选择主动关闭同服务器的连接.在服务器的角度看,服务器是客户端连接套接字read系统调用返回0,触发关闭逻辑,服务器本地是被动关闭连接的. 但是在某些场景中,客户端虽然已经实际断开了与服务器的连接,但是服务器并不能及时检测出此时维护的连接已经断开的情景.在这种情况下,由于被动关闭的缘故,服务器并不会主动释放与该连接有关的资源.这些不能被释放的资

项目架构开发:服务层(下)

之前我们已经完成了服务层,因为当时展现层还没有出来,所以只做了简单介绍.传送门:项目架构开发:服务层(上) 这次我们通过一个维护系统用户的场景来介绍一下服务层真正的设计用意. 1.新增用户场景 新增用户可能会有以下步骤 实现以上需求,开发人员一般情况下可能就是以上 蓝红黑紫绿 几种选择 1.有些写在Controllers.有些写在Application 2.都写在Controllers或都写在Application 3.有些写在DAL层.甚至存储过程 特别是新手以及那些拿来主义的人,他们不会花更

分层架构中的服务层

http://www.uml.org.cn/zjjs/201009141.asp 简介 引言 服务层不直接执行任何任务.它所做的就是合理的安排一些列你提供的业务对象.服务层很清楚业务逻辑层,也很清楚领域模型.例如:你使用数据库表模型模式的业务逻辑层,服务层会通过DataSet来进行交互. 很显然,服务层合理的安排业务组件,同时也合理的安排应用的服务.工作流和业务逻辑的其他组件. 服务层的职责 服务层是一个额外的层,是在两个层之间设置一个边界. 服务层的目的是什么? 在业界有很多的应用原则都很重要

微服务开发中的数据架构设计

本文来自作者 陈伟荣 在 GitChat 分享的文章[微服务开发中的数据架构设计] 前言 微服务是当前非常流行的技术框架,通过服务的小型化.原子化以及分布式架构的弹性伸缩和高可用性,可以实现业务之间的松耦合.业务的灵活调整组合以及系统的高可用性.为业务创新和业务持续提供了一个良好的基础平台.本文分享在这种技术架构下的数据架构的设计思想以及设计要点,本文包括下面若干内容. 微服务技术框架中的多层数据架构设计 数据架构设计中的要点 要点1:数据易用性 要点2:主.副数据及数据解耦 要点3:分库分表

微服务架构(Microservice Architecture)

之前一段时间,有听部门架构说起接下来公司要使用微服务架构来研发系统,当时没怎么在意,因为是第一次听说微服务这个名词(果然无知者无畏啊):正好赶上五一假, 我自告奋勇的,接了编写微服务架构培训文档这个任务(也许因为我是文科生,文笔稍微好点).五一假期三天,基本都是在看资料,梳理思路以及编写接下来的培训文档中度过. 下面,就说说我这几天的一些收获吧:先说说资料来源吧:有架构给我的一些资料,以及自己百度和论坛.社区找来的一些资料,权当做一个总结式的简介... 目录如下: 一.微服务架构介绍 二.出现和

CRUD全栈式编程概述

业务场景 CRUD,从数据驱动的角度几乎所有的的业务都是在做这样的事情.  几乎所有的操作都是在做对表的增删该查.  假设我们将数据库数据规个类:  分为基础/配置数据和业务/增长数据,或者说静态数据和动态数据.  其中静态数据是由后台管理员编辑的产生,动态数据是由客户产生.  那么这部分中的静态数据往往伴随着完整的增删改查逻辑.  完整的增删改查逻辑指的是,有对数据库某个表数据的查询.  一条或者几条数据的添加,删除,修改.  再直白一点就是有个界面,上面有查询,添加,删除,修改,导入,导出的