实体框架,Unity和MVC

时间:2015-02-04 21:11:48

标签: asp.net-mvc entity-framework unity-container

我有一个使用Entity Framework,MVC和Unity的多层应用程序。 基本设置如下:

EF数据访问层

public class MyDataProvider : DbContext, IMyDataProvider 
{


    public MyDataProvider(SqlConnection existingConnection, bool contextOwnsConnection)
        : base(existingConnection,contextOwnsConnection)
    {
        ((IObjectContextAdapter)this).ObjectContext.CommandTimeout = 60;

        Configuration.LazyLoadingEnabled = true;
        Configuration.ValidateOnSaveEnabled = true;
        Configuration.ProxyCreationEnabled = true;
        Configuration.AutoDetectChangesEnabled = true;

    }

    public new IDbSet<TModel> Set<TModel>() where TModel : class
    {
        return base.Set<TModel>();
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new EmployeeMapping());
        base.OnModelCreating(modelBuilder);
    }

public abstract class ServiceBase<TModel> : IDisposable, IService<TModel> where TModel : class, IModel
{
    [Dependency]
    public IMyDataProvider MyDataProvider { get; set; }
    ...
}

所有服务都继承自此类

然后我将特定服务注入业务逻辑层,如下所示:

public class GetEmployees
{
    [Dependency("EmployeeService")]
    public IEmployeeService EmployeeService { get; set; 

    public IQueryable<Employee> GetAllEmployees()
    {
        return EmployeeService.GetTable();
    }

    ...
}    

在MVC中我使用控制器工厂

public class MyControllerFactory : DefaultControllerFactory
{
    private IUnityContainer _container;

    public MyControllerFactory(IUnityContainer container)
    {
        _container = container;
    }
    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
    {
        if (controllerType != null)
        {
            return _container.Resolve(controllerType) as IController;
        }
        else
        {
            return base.GetControllerInstance(requestContext, controllerType);
        }
    }

Global.asax中

private static IUnityContainer InitContainer()
    {
        IUnityContainer unityContainer = new UnityContainer();
        Bootstrapper bootstrapper = new Bootstrapper(unityContainer);

        return unityContainer;
    }

我将UnityContainer的实例传递给Bootstrapper类。 Bootstrapper类自我注册所有程序集。

在MVC控制器中,我像这样注入业务逻辑:

public class EmployeeController
{
    [Dependency("GetEmployees")]
    public IBusinessLogic GetEmployees_Operations { get; set; }

    public ActionResult EmployeeMain()
    {   
        var employees = GetEmployees_Operations.GetAllEmployees();
        ...
    }
}

这一切都很有效。我经常会从MyDataProvider类中抛出一个异常:“EntityConnection只能用一个封闭的DbConnection构造”。这似乎发生在MVC网站的高使用期间。这个例外很容易理解,但我该如何解决呢?

我发现更改我将业务逻辑类从控制器上的字段实例化到ActionResult方法内的方式,我没有收到异常。

例如:

public class EmployeeController
{
    //[Dependency("GetEmployees")]
    //public IBusinessLogic GetEmployees_Operations { get; set; }

    public ActionResult EmployeeMain()
    {   
        IBusinessLogic GetEmployees_Operations = _ioc_Bootstrapper.Resolve(typeof(IBusinessLogic), "GetEmployees") as IBusinessLogic;
        var employees = GetEmployees_Operations.GetAllEmployees();
        ...
    }
}

我是否完全错过了这条船并且错误地实施了Unity?

Bootstrapper代码

private void RegisterDAL(String assembly)
    {
        var currentAssembly = Assembly.LoadFrom(assembly);
        var assemblyTypes = currentAssembly.GetTypes();

        foreach (var assemblyType in assemblyTypes)
        {
            ...
            if (assemblyType.FullName.EndsWith("Provider"))
            {
                foreach (var requiredInterface in assemblyType.GetInterfaces())
                {
                    if (requiredInterface.FullName.EndsWith("DataProvider"))
                    {
                        var typeFrom = assemblyType.GetInterface(requiredInterface.Name);
                        var typeTo = assemblyType;
                        var injector = GetInjectorConstructor(assemblyType.Module.Name);
                        RegisterType(typeFrom, typeTo, false, injector);
                    }
                }

                continue;
            }

            ...
    }     

 private InjectionConstructor GetInjectorConstructor(String moduleName) 
 {
  ...
  connString = String.Concat("Data Source=MySqlServer, ";Initial Catalog=", catalogName, ";Application Name=", applicationName, ";Integrated Security=True; );
  var conn = new SqlConnection(connString);
  return new InjectionConstructor(conn, true);
  }

0 个答案:

没有答案