Using StructureMap DI and Generic Repository
In this post, i will show how to use generic repository and dependency injection using structuremap. I will be using LINQ to SQL.
Generic Repository
The interface for the generic repository is like this:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
public interface IRepository<T> where T : class { void Create(T entity); void Update(T entity); void Delete(T entity); void Copy(T source, T target); void Flush(); T Get(Expression<Func<T, bool>> predicate); IEnumerable<T> GetAll(); System.Data.Linq.Table<T> Table { get; } int Count(Expression<Func<T, bool>> predicate); IEnumerable<T> Fetch(Expression<Func<T, bool>> predicate); IEnumerable<T> Fetch(Expression<Func<T, bool>> predicate, Action<Orderable<T>> order); IEnumerable<T> Fetch(Expression<Func<T, bool>> predicate, Action<Orderable<T>> order, int skip, int count); } |
Now lets go to the implementation of the generic repository interface.
|
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
|
public class Repository<T> : IRepository<T> where T : class { protected IDataContextFactory _dataContextFactory; public Repository(IDataContextFactory dataContextFactory) { _dataContextFactory = dataContextFactory; } public System.Data.Linq.Table<T> Table { get { return _dataContextFactory.Context.GetTable<T>(); } } IEnumerable<T> IRepository<T>.GetAll() { return Table.ToReadOnlyCollection(); } #region IRepository<T> Members void IRepository<T>.Create(T entity) { Table.InsertOnSubmit(entity); _dataContextFactory.SaveAll(); } void IRepository<T>.Update(T entity) { if (Table.GetOriginalEntityState(entity) == null) { Table.Attach(entity); } _dataContextFactory.Context.Refresh(System.Data.Linq.RefreshMode.KeepCurrentValues, entity); _dataContextFactory.SaveAll(); } void IRepository<T>.Delete(T entity) { Table.DeleteOnSubmit(entity); _dataContextFactory.SaveAll(); } T IRepository<T>.Get(Expression<Func<T, bool>> predicate) { return Table.FirstOrDefault(predicate); } int IRepository<T>.Count(Expression<Func<T, bool>> predicate) { return Table.Count(predicate); } public virtual IQueryable<T> Fetch(Expression<Func<T, bool>> predicate) { return Table.Where(predicate); } public virtual IQueryable<T> Fetch(Expression<Func<T, bool>> predicate, Action<Orderable<T>> order) { var orderable = new Orderable<T>(Fetch(predicate)); order(orderable); return orderable.Queryable; } public virtual IQueryable<T> Fetch(Expression<Func<T, bool>> predicate, Action<Orderable<T>> order, int skip, int count) { return Fetch(predicate, order).Skip(skip).Take(count); } IEnumerable<T> IRepository<T>.Fetch(Expression<Func<T, bool>> predicate) { return Fetch(predicate).ToReadOnlyCollection(); } IEnumerable<T> IRepository<T>.Fetch(Expression<Func<T, bool>> predicate, Action<Orderable<T>> order) { return Fetch(predicate, order).ToReadOnlyCollection(); } IEnumerable<T> IRepository<T>.Fetch(Expression<Func<T, bool>> predicate, Action<Orderable<T>> order, int skip, int count) { return Fetch(predicate, order, skip, count).ToReadOnlyCollection(); } #endregion } |
If you notice ToReadOnlyCollection() this is an extension method of the IEnumerable. This is defined as:
|
1
2
3
4
5
6
|
using System.Collections.ObjectModel; public static IList<T> ToReadOnlyCollection<T>(this IEnumerable<T> enumerable) { return new ReadOnlyCollection<T>(enumerable.ToList()); } |
I think thats if for our generic repository. To use it, for example if we have a Blog model on our LINQ to SQL we can use the repository like:
|
1
|
IRepository<Blog> BlogRepository = new Repository<Blog>(); |
Using StructureMap Dependency Injector
Before reading this, I assume that the reader has knowledge already about dependency injection.
First we have to reference the StructureMap DLL. It can be downloaded on the structuremap website.
Then we have to create the Registry Class. This class will configure the dependencies. This class should be of type StructureMap.Configuration.DSL.Registry
The Registry class may look like this:
|
1
2
3
4
5
6
7
8
|
public class ApplicationRegistry : Registry { public ApplicationRegistry() { For(typeof(IRepository<Blog>)).Use(typeof(Repository<Blog>)); For(typeof(IDataContextFactory)).Use(typeof(DataContext)); } } |
After configuring the dependency, we will going to add our Registry to the StructureMap configuration. Usually, this will be on a Bootstrapper class that looks like this:
|
1
2
3
4
5
6
7
8
9
10
|
public static class Bootstrapper { public static void ConfigureStructureMap() { ObjectFactory.Initialize(x => { x.AddRegistry(new ApplicationRegistry()); }); } } |
This code tells the application to use the dependency injection as configure on the registry class. This should be called on program startup, the main method on console application or on global.asax on web application.
|
1
|
Bootstrapper.ConfigureStructureMap(); |
To get the instance of the repository:
|
1
|
IRepository<Blog> Repository = ObjectFactory.GetInstance<IRepository<Blog>>(); |
That should be it. Its ready.
If you have questions, please leave comments. I would be happy to answer.
If you want to create test repository that give predictable data, you should have another configuration for your test. Another boot strapper class perhaps but this is for test specific repository configuration. And on your test project call the test boot strapper not the original one.
Or just use mocking for testing like my code below using MOQ:
[TestMethod] public void GetUserByIDTest() { User user = new User() { UserID = 1, UserName = “mcxiand”, Password = “password”, }; var userid = 1; //initialize mock var mock = new Mock<IRepository>(); //see if the method in something you have mocked has been called by using Verify(). mock.Setup(x => x.Get(It.IsAny<Expression<Func>>())).Returns(user);
//Initialize Service service = new UserService(mock.Object); //call the method to test var u = service.GetUser(userid);
//Assert Assert.AreEqual(u.UserID, userid, “not equal”); }
http://mcxiand.wordpress.com/2010/05/13/using-structuremap-di-and-generic-repository/
Using StructureMap DI and Generic Repository的更多相关文章
- Generic repository pattern and Unit of work with Entity framework
原文 Generic repository pattern and Unit of work with Entity framework Repository pattern is an abstra ...
- EF6 CodeFirst+Repository+Ninject+MVC4+EasyUI实践(完)
前言 这一篇是本系列的最后一篇,虽然示例讲到这里就停止呢,但对于这些技术的学习远不能停止.虽然本示例讲的比较基础,但是正如我第一篇说到的,这个系列的目的不是说一些高端的架构设计,而是作为一个入门级,对 ...
- Follow me to learn what is repository pattern
Introduction Creating a generic repository pattern in an mvc application with entity framework is th ...
- Using the Repository Pattern with ASP.NET MVC and Entity Framework
原文:http://www.codeguru.com/csharp/.net/net_asp/mvc/using-the-repository-pattern-with-asp.net-mvc-and ...
- [转]Using the Repository Pattern with ASP.NET MVC and Entity Framework
本文转自:http://www.codeguru.com/csharp/.net/net_asp/mvc/using-the-repository-pattern-with-asp.net-mvc-a ...
- Using the Repository and Unit Of Work Pattern in .net core
A typical software application will invariably need to access some kind of data store in order to ca ...
- 单元操作和仓储模式 repository+unitOfWork
仓储和工作单元模式是用来在数据访问层和业务逻辑层之间创建一个抽象层.应用这些模式,可以帮助用来隔离你的程序在数据存储变化. 在数据源层和业务层之间增加一个repository层进行协调,有如下作用:1 ...
- 6.在MVC中使用泛型仓储模式和依赖注入实现增删查改
原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/crud-operations-using-the-generic-repository-pat ...
- MVC中使用泛型仓储模式和依赖注入
在ASP.NET MVC中使用泛型仓储模式和依赖注入,实现增删查改 原文链接:http://www.codeproject.com/Articles/838097/CRUD-Operations-Us ...
随机推荐
- APUE读书笔记:关于sigsuspend
sigsuspend是一个原子操作,为了防止信号丢失而存在的,具体含义看下函数原型. int sigsuspend(const sigset_t *mask); 先忽略参数,sigsuspend完成的 ...
- Qt使用中碰到的问题
1.发现table第一列在切换后变黑,或多了行数. 一般是编译出来的.exe文件所使用的qt的dll不匹配造成的.一定要使用编译时,所使用的那个版本的qt的dll.
- TOMCAT-publishing to tomcat v7.0 server at
因为tomcat的work文件没有清空,导致MyEclipse部署在server.xml文件中的项目路径是错误的. 解决办法:清空work文件夹 下面这个勾勾是MyEclipse自动发布项目路径的选项
- spring @Autowired或@Resource 的区别
1.@Autowired与@Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法上. 2.@Autowired默认按类型装配(这个注解是属于spring的),默认情况下必 ...
- OpenGL红宝书例子2.2 uniform变量的使用
1. 简单介绍一下OpenGL可编程渲染管线的流程 顶点着色 --> 细分着色 --> 几何着色 --> 片元着色 --> 计算着色 一般我们主要参与的阶段是顶点着色和片元着色 ...
- JS day01——window对象、执行顺序、线程模型
1.window对象 window对象表示当前浏览器的窗口,它是一个顶级对象,我们创建的所有对象.函数.变量都是window对象的成员. window对象自带了一些非常有用的方法.属性. window ...
- html dom模型一
DOM 节点 包含的节点内容: 根据 W3C 的 HTML DOM 标准,HTML 文档中的所有内容都是节点: 整个文档是一个文档节点 每个 HTML 元素是元素节点 HTML 元素内的文本是文本节点 ...
- linux下执行scrapy的爬虫定时任务
刚开始执行scrapy crawl zentaos可以完成扫描 但是通过linux的crontab任务,只执行了连接mongodb的操作,并创建了索引 也就是说scrapy crawl zentaos ...
- Magento首页显示产品
Magento首页显示产品 经常用的比较琐碎,上官网发现一个稍微全一点的不过没有针对 具体使用过程中遇到的情况进行修正 这边只做一个备忘吧 (细节问题 按个别情况进行修改即可) New ...
- Chapter 1 First Sight——15
The red-haired woman looked up. "Can I help you?" 红头发的女人抬头看了一眼说,有什么我能帮助你的吗? "I'm Isab ...