如何使用Unity容器注册Generic类型

时间:2016-06-25 14:31:29

标签: generics dependency-injection unity-container repository-pattern

我正在努力使用Unity将通用类型存储库注入我的服务类。至少,我认为这个通用存储库是造成麻烦的原因。有人可以指出我做错了什么吗?请相信我,因为我是Unity的新手。首先,这是错误消息,我收到以下错误。

依赖项的解析失败,type =“TestUnity.Services.Contracts.ICustBillingTypeService”,name =“(none)”。 在解决时发生异常。

异常是:InvalidOperationException - 无法构造String类型。您必须配置容器以提供此值。

在例外时,容器是:

解析TestUnity.Services.Implementations.CustBillingTypeService,(none)(从TestUnity.Services.Contracts.ICustBillingTypeService映射,(无))   解析构造函数TestUnity.Services.Implementations.CustBillingTypeService的参数“repo”(TestUnity.Repositories.Contracts.IRepository 1[[TestUnity.DAL.CustBillingType, TestUnity.DAL, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] repo) Resolving TestUnity.Repositories.Implementations.Repository 1 [TestUnity.DAL.CustBillingType],(none)(从TestUnity.Repositories.Contracts.IRepository {映射{1}} 1 [[TestUnity.DAL.CustBillingType,TestUnity.DAL,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null]](TestUnity.Repositories.Contracts.IDataContext ctx)       解析TestUnity.Repositories.Implementations.DataContext,(无)(从TestUnity.Repositories.Contracts.IDataContext映射,(无))       解析构造函数TestUnity.Repositories.Implementations.DataContext(System.String nameOrConnectionString)的参数“nameOrConnectionString”         解析System.String,(无)

这是我的Unity引导类,它位于一个单独的类库

1[TestUnity.DAL.CustBillingType], (none))
    Resolving parameter "ctx" of constructor TestUnity.Repositories.Implementations.Repository

请注意,在我的测试用例中,我并没有嘲笑任何事情。这是一种集成测试。

如果我不得不猜测,我认为通用类型注册有问题。或者它可能完全不同。

巴布。

1 个答案:

答案 0 :(得分:0)

您正在将import UIKit import Alamofire import SwiftyJSON class DetailsViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { @IBOutlet weak var TableDeliveryDetails: UITableView! @IBOutlet weak var bostampLabel: UILabel! @IBOutlet weak var distribuidorLabel: UILabel! @IBOutlet weak var exploracaoLabel: UILabel! @IBOutlet weak var dataLabel: UILabel! @IBOutlet weak var descargaLabel: UILabel! var bostampLabelText="" var distribuidorLabelText="" var exploracaoLabelText="" var dataLabelText="" var descargaLabelText="" var getsDetailsCollection = [GetDeliveryDetailsClass]() override func viewDidLoad() { super.viewDidLoad() self.TableDeliveryDetails.dataSource=self self.TableDeliveryDetails.delegate=self self.TableDeliveryDetails.registerClass(TableViewCellDetails.self, forCellReuseIdentifier: "cell") //bostampLabel.text=bostampLabelText distribuidorLabel.text=distribuidorLabelText exploracaoLabel.text=exploracaoLabelText dataLabel.text=dataLabelText descargaLabel.text=descargaLabelText Alamofire.request(.GET, "http://192.168.0.1:1278/api/Delivery/GetDeliveryDetais", parameters: ["stamp": bostampLabelText]) .responseJSON { response in print(response.request) // original URL request print(response.response) // URL response print(response.data) // server data print(response.result) // result of response serialization if let JSON = response.result.value { let jsonResults = JSON as! NSArray for var i = 0; i < jsonResults.count; i++ { var produto=jsonResults[i]["Produto"] as! String var qttKg = jsonResults[i]["QuantidadeKG"] as! Double var qttLt = jsonResults[i]["QuantidadeLT"] as! Double var getObj = GetDeliveryDetailsClass(produto:produto,qttKg:qttKg,qttLt:qttLt) self.getsDetailsCollection.append(getObj) // print(add) // TableClienteFinal.append(add) } } self.reload_table_data() } } func reload_table_data() { dispatch_async(dispatch_get_main_queue(),{ self.TableDeliveryDetails.reloadData() return }) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return self.getsDetailsCollection.count } func numberOfSectionsInTableView(tableView: UITableView) -> Int { return 1 } func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { // let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! TableViewCellDetails let cell = tableView.dequeueReusableCellWithIdentifier("cell") as! TableViewCellDetails let object = self.getsDetailsCollection[indexPath.row] cell.columProdutoText=object.produto cell.columQttKgText=String(format:"%f", object.qttKg) cell.columnQttLtText=String(format:"%f", object.qttLt) return cell } 映射到IDataContext,如下所示:

DataContext

container.RegisterType<IDataContext, DataContext>(); 构造函数需要一个连接字符串/名称作为您不提供的参数。

要么像这样提供这个值:

DataContext

或使用container.RegisterType<IDataContext, DataContext>( new InjectionConstructor("name=TestModel")); 代替TestModel。我想这就是你打算做的。 DataContext已经有一个默认构造函数,因此您不需要提供连接字符串:

TestModel

IMO,在Composition Root(在您的示例中是container.RegisterType<IDataContext, TestModel>(); 类)中显示连接字符串是有意义的,并且没有在{{1的默认构造函数中对其进行硬编码}}。连接字符串基本上是primitive dependency,您可能希望将来更改。