WF Unity或IoC / DI的另一种方式

时间:2017-06-11 16:08:25

标签: dependency-injection repository inversion-of-control unity-container

大家晚上好。 目前,我是IoC / DI的新人。我有一个带C#的Winform项目。请查看一些代码并帮我解决以下问题:

1 / IRepository

namespace Framework.Repositories
{
    public interface IRepository<T> : IDisposable where T:class
    {
        T Get(int id);
        IEnumerable<T> GetAll();
        IEnumerable<T> Find(Expression<Func<T, bool>> predicate);
    }
}

2 /存储库

namespace Framework.Repositories
{
    public class Repository<T> : IRepository<T> where T : class
    {
        private bool _disposed = false;
        private static bool _isTransactionStarted;
        protected readonly DbContext Context;
        private DbContextTransaction _transaction { get; set; }

        public Repository(DbContext context)
        {
            Context = context;
            _isTransactionStarted = false;

            if (context == null)
                throw new NullReferenceException(nameof(context));

            if (Context.Set<T>() == null)
                throw new NullReferenceException("_context.Set<T>()");
        }

        public T Get(int id) => Context.Set<T>().Find(id);

        public IEnumerable<T> GetAll() => Context.Set<T>().ToList();

        public IEnumerable<T> Find(Expression<Func<T, bool>> predicate) => Context.Set<T>().Where(predicate);

    }
}

3 / Model

namespace PRO.Model
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;
    using System.Data.Entity.Spatial;

    [Table("Employee")]
    public partial class Employee
    {
        [Key]
        public long EmpId { get; set; }

        [StringLength(15)]
        public string Username { get; set; }

        public string Password { get; set; }

        [StringLength(50)]
        public string UserGroup { get; set; }

        [Required]
        [StringLength(50)]
        public string FirstName { get; set; }

        [StringLength(50)]
        public string LastName { get; set; }

        [Required]
        [StringLength(1)]
        public string EmpStatus { get; set; }

    }
}

4 / IEmployeeRepository

namespace PRO.Repositories
{
    public interface IEmployeeRepository:IRepository<Employee>
    {
        Employee UserLogin(string username, string password);
    }
}

5 / EmployeeRepository

namespace PRO.Repositories
{
    public class EmployeeRepository : Repository<Employee>,IEmployeeRepository
    {
        public EmployeeRepository(DbContext context) : base(context)
        {
        }

        public Employee UserLogin(string username, string password)
        {
            try
            {
                return Find(x=>x.Username == username && x.Password == password && x.EmpStatus == BooleanType.Yes ).FirstOrDefault();
            }
            catch (Exception ex)
            {
                throw new RepositoryException(ex);
            }

        }

        public MyDbContext myDbContext => Context as MinhTamHotelDbContext;
    }
}

6 / IEmployeeService

namespace PRO.Services
{
    public interface IEmployeeService
    {
        Employee UserLogin(string username, string password);
    }
}

7 / EmployeeService

namespace PRO.Services
{
    public class EmployeeService : IEmployeeService
    {
        public IEmployeeRepository EmployeeRepos { get; set; }


        public Employee UserLogin(string username, string password)
        {
            return EmployeeRepos.UserLogin(username, password);
        }
    }
}

8 / DbContext

namespace PRO.Repositories
{
    using System.Data.Entity;

    public partial class MyHotelDbContext: DbContext
    {
        public MyHotelDbContext()
            : base("name=MyHotelDbContext")
        {
        }

        public virtual DbSet<Employee> Employees { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
               //DbContext Here
        }
    }
}

9 / App.config中

<configSections>
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration, Version=2.1.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
  </configSections>


<connectionStrings>
    <add name="MinhTamHotelDbContext" connectionString="data source=.;initial catalog=WiF;persist security info=True;user id=sa;password=@success@;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" />
  </connectionStrings>

<alias alias="transient" type="Microsoft.Practices.Unity.TransientLifetimeManager, Microsoft.Practices.Unity, Version=2.1.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<alias alias="perResolve" type="Microsoft.Practices.Unity.PerResolveLifetimeManager, Microsoft.Practices.Unity, Version=2.1.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<alias alias="singleton" type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager, Microsoft.Practices.Unity, Version=2.1.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />

<alias alias="AreaRepository" type="PRO.Repositories.AreaRepository, PRO.Repositories, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<alias alias="IAreaRepository" type="PRO.Repositories.IAreaRepository, PRO.Repositories, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<alias alias="EmployeeRepository" type="PRO.Repositories.EmployeeRepository, PRO.Repositories, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<alias alias="IEmployeeRepository" type="PRO.Repositories.IEmployeeRepository, PRO.Repositories, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<alias alias="GnrlCodeRepository" type="PRO.Repositories.GnrlCodeRepository, PRO.Repositories, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<alias alias="IGnrlCodeRepository" type="PRO.Repositories.IGnrlCodeRepository, PRO.Repositories, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />

<alias alias="AreaService" type="PRO.Services.AreaService, PRO.Services, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<alias alias="IAreaService" type="PRO.Services.IAreaService, PRO.Services, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<alias alias="EmployeeService" type="PRO.Services.EmployeeService, PRO.Services, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<alias alias="IEmployeeService" type="PRO.Services.IEmployeeService, PRO.Services, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<alias alias="GnrlCodeService" type="PRO.Services.GnrlCodeService, PRO.Services, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<alias alias="IGnrlCodeService" type="PRO.Services.IGnrlCodeService, PRO.Services, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />

<alias alias="IRepository" type="Framework.Repositories.IRepository, Framework.Repositories, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<alias alias="Repository" type="Framework.Repositories.Repository, Framework.Repositories, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />

<container>


  <register type="IAreaRepository" mapTo="AreaRepository">
    <lifetime type="perResolve" />
  </register>
  <register type="IEmployeeRepository" mapTo="EmployeeRepository">
    <lifetime type="perResolve" />
  </register>

  <register type="IGnrlCodeRepository" mapTo="GnrlCodeRepository">
    <lifetime type="perResolve" />
  </register>

  <register type="IEmployeeService" mapTo="EmployeeService">
    <property name="EmployeeRepos" dependencyType="IEmployeeRepository" />
    <lifetime type="perResolve" />
  </register>

  <register type="IGnrlCodeService" mapTo="GnrlCodeService">
    <property name="GnrlCodeRepos" dependencyType="IGnrlCodeRepository" />
    <lifetime type="perResolve" />
  </register>

  <register type="IAreaService" mapTo="AreaService">
    <property name="AreaRepos" dependencyType="IAreaRepository" />
    <lifetime type="perResolve" />
  </register>

</container>

10 /在我的登录表单中

public partial class UserLogin : Form
{
    private IEmployeeService _employeeSvr = null;

    public IEmployeeService EmployeeSrv
    {
        get { return _employeeSvr ?? (_employeeSvr = UnityInstanceProvider.CreateInstance<IEmployeeService>()); }
        set { _employeeSvr = value; }
    }


    private void btnLogin_Click(object sender, System.EventArgs e)
    {
        try
        {
            this.Cursor = Cursors.WaitCursor;

            var employee = EmployeeSrv.UserLogin(txtUsername.Text.TrimEx(), txtPassword.Text.TrimEx());

            //MsgBox.ShowInfoMsg(employee.ToJsonObject().ToStringEx());

            if (employee != null)
            {
                Visible = false;
                AreaMap.Instance.Show();
            }
        }
        catch (Exception ex)
        {
            ex.ExceptionHandler();
        }
        finally
        {
            this.Cursor = Cursors.Default;
        }
  }

}

我的错误是:

Resolution of the dependency failed, type = "PRO.Services.IEmployeeService", name = "(none)".
Exception occurred while: while resolving.
Exception is: InvalidOperationException - The type DbConnection does not have an accessible constructor.
-----------------------------------------------
At the time of the exception, the container was:

  Resolving PRO.Services.EmployeeService,(none) (mapped from PRO.Services.IEmployeeService, (none))
  Resolving value for property EmployeeService.EmployeeRepos
    Resolving PRO.Repositories.EmployeeRepository,(none) (mapped from PRO.Repositories.IEmployeeRepository, (none))
    Resolving parameter "context" of constructor PRO.Repositories.EmployeeRepository(System.Data.Entity.DbContext context)
      Resolving System.Data.Entity.DbContext,(none)
      Resolving parameter "existingConnection" of constructor System.Data.Entity.DbContext(System.Data.Common.DbConnection existingConnection, System.Data.Entity.Infrastructure.DbCompiledModel model, System.Boolean contextOwnsConnection)
        Resolving System.Data.Common.DbConnection,(none)

有人可以帮我解决这个问题吗? 如果Unity不支持多重继承(EmployeeRepository:Repository,IEmployeeRepository),还有其他方法可以替换Unity吗?

非常感谢

0 个答案:

没有答案