zoukankan      html  css  js  c++  java
  • 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/

  • 相关阅读:
    json数据转为对象,一般在前台把数据传回后端中使用 转https://www.cnblogs.com/zxtceq/p/6610214.html
    JavaScript事件大全3
    javascript大全
    Javascript刷新页面大全
    JavaScript验证正则表达式大全
    insertAdjacentHTML和insertAdjacentText方法
    CSS实现样式布局
    iis浏览网页时提示无法显示 XML 页
    IIS浏览提示无法显示网页的解决方法
    在dreamweaver中输入代码时不会有提示的解决办法
  • 原文地址:https://www.cnblogs.com/zcm123/p/3271776.html
Copyright © 2011-2022 走看看