日期:2014-05-17  浏览次数:20478 次

请教一个关于依赖注入的问题
请教一个关于依赖注入调用的问题。
我有一个创建客户信息的功能,分别定义了一个实体类Customer,一个数据层接口ICustomerDataAccess,一个数据层实现类CustomerDataAccess,及业务逻辑CustomerBusiness。
其中,为了在业务逻辑CustomerBusiness中隐藏对CustomerDataAccess的依赖,所以在CustomerBusiness中用了构造函数来依赖注入。代码如下
C# code


public class Customer
{
        public int CustomerId{get;set;}

        public string CustomerName{get;set;}

        public string Address{get;set;}
}

public interface ICustomerDataAccess
{
        bool Add(Customer customer);
}

//数据访问
public class CustomerDataAccess : ICustomerDataAccess
{
        public bool Add(Customer customer)
        {
                string sql = @"INSERT INTO dbo.Customer (CustomerName,Address) VALUES (CustomerName,@Address)";
               SqlParameter[] param = {
        new SqlParameter("@CustomerName",customer.CustomerName),
        new SqlParameter("@Address",customer.Address)
    };
    return SQLHelper.ExecuteNoQuery(sql,param);
        }
}

//业务逻辑
public class CustomerBusiness
{
       ICustomerDataAccess _customerDataAccess;
       
        //如果用这个构造函数实例化的话,就还是让CustomerBusiness依赖了具体的Customer实现(CustomerDataAccess)
        //所以用了一个带参数的构造函数注入
        //public CustomerBusiness()
        //{
    //   _customerDataAccess = new CustomerDataAccess();
        //}

        public CustomerBusiness(ICusomterDataAccess customerDataAccess)
        {
              _customerDataAccess = customerDataAccess;
        }

        public bool CreateCustomer(Customer customer)
        {
             return _customerDataAccess.Add(customer);
        }
}




现在我有点不明白的是,那我怎么在Web的页面里调用CustomerBusiness呢?因为我用了一个带参数的构造函数来注入减少依赖,那我不是要在Web的页面里传一个具体的数据实现(CustomerDataAccess)了?如下:
C# code


protected void btnSave_Click(object sender,EventArgs e)
{
      //CustomerBusiness business = new CustomerBusiness(
      //就是这里该怎么调用CustomerBusiness呢?
}





------解决方案--------------------
一般都得配合反射才行,配置文件里写需要什么数据访问类,业务逻辑通过反射得到CustomerDataAccess。

不反射的话,你就要手工维护一段case代码了,通过一个配置文件里取出的字符串比较,new 出一个CustomerDataAccess返回,这样以后这就新的dataaccess都要手工修改这段代码,就是一个工程模式。
------解决方案--------------------
最简单的方式是工厂方式:
你创建个class:
C# code

public class CustomerDataAccessFactory {
    //里面有个获取实例的方法
     public static GetInstance() {
        //根据配置文件或写死 实例化哪个实体类
         ICusomterDataAccess customerDataAccess = new XXXXXXX();
        return customerDataAccess ;
    }
}

------解决方案--------------------
探讨
引用:

<add key="ICustomerDataAccess" value="ST.EIP.DataAccess.Interface.ICustomerDataAccess" />这样?

------解决方案--------------------
1.你的问题和解法无关,web里面其实不管,bil自己配对即可,web只管调用并不关心他们如何配对
2.有关注入,实现手段很多,我个人选择MEF,你只需要做好特性标记,让MEF自己去搜索组合他们就好了,MEF还是比较方便的,既不用修改代码,也不用修改配置文件。只是依靠元数据特性让MEF自己组合就好。
------解决方案--------------------
protected void btnSave_Click(object sender,EventArgs e)
{
//CustomerBusiness business = new CustomerBusiness(
//就是这里该怎么调用CustomerBusiness呢?
}
其实这个地方 和你在业务逻辑调用接口是一样的,都不应该 去 new ,依赖注入最基本特征就是不需要去new

但是你需要为CustomerBusiness business 这个对象指定一个 setter ,不知道你的spring 怎么配置的