8

Tôi làm việc trong môi trường VB.Net và gần đây đã được giao nhiệm vụ tạo môi trường MVC để sử dụng làm cơ sở để làm việc. Tôi quyết định chuyển đổi bản phát hành mới nhất của SharpArchitecture (Q3 2009) thành VB, mà trên toàn bộ đã ổn sau một chút kéo tóc. Tôi đã gặp một vấn đề với Castle Windsor, nơi giao diện kho lưu trữ tùy chỉnh của tôi (sống trong dự án lõi/miền) đã được tham chiếu trong constructor của bộ điều khiển thử nghiệm của tôi không được tiêm với việc thực hiện cụ thể (từ dự án dữ liệu). Tôi nhấn một bức tường gạch với điều này về cơ bản quyết định chuyển ra Castle Windsor cho StructureMap.Vấn đề Triển khai StructureMap trong VB.Net Chuyển đổi SharpArchitecture

Tôi nghĩ rằng tôi đã thực hiện điều này ok khi tất cả mọi thứ biên dịch và chạy và bộ điều khiển của tôi chạy ok khi tham chiếu một giao diện kho lưu trữ tùy chỉnh. Nó xuất hiện bây giờ mà tôi có/hoặc không thể bây giờ thiết lập giao diện chung của tôi lên đúng cách (tôi hy vọng điều này có ý nghĩa cho đến nay như tôi mới cho tất cả điều này). Khi tôi sử dụng IRepository (Of T) (muốn nó được tiêm với một thực hiện cụ thể của Repository (Of Type)) trong constructor điều khiển tôi nhận được lỗi runtime sau đây:

"StructureMap Exception Code: 202 No Default Ví dụ được xác định cho PluginFamily SharpArch.Core.PersistenceSupport.IRepository`1 [[DebtRemedy.Core.Page, DebtRemedy.Core, Phiên bản = 1.0.0.0, Văn hóa = trung lập, PublicKeyToken = null]], SharpArch.Core, Phiên bản = 1.0.0.0 , Văn hóa = trung lập, PublicKeyToken = b5f559ae0ac4e006 "

Dưới đây là các đoạn mã của tôi mà tôi đang sử dụng (dự án của tôi được gọi là DebtRemedy).

My lớp StructureMap registry

Public Class DefaultRegistry 
    Inherits Registry 

    Public Sub New() 
     ''//Generic Repositories 
     AddGenericRepositories() 
     ''//Custom Repositories 
     AddCustomRepositories() 
     ''//Application Services 
     AddApplicationServices() 
     ''//Validator 
     [For](GetType(IValidator)).Use(GetType(Validator)) 
    End Sub 

    Private Sub AddGenericRepositories() 
     ''//ForRequestedType(GetType(IRepository(Of))).TheDefaultIsConcreteType(GetType(Repository(Of))) 
     [For](GetType(IEntityDuplicateChecker)).Use(GetType(EntityDuplicateChecker)) 
     [For](GetType(IRepository(Of))).Use(GetType(Repository(Of))) 
     [For](GetType(INHibernateRepository(Of))).Use(GetType(NHibernateRepository(Of))) 
     [For](GetType(IRepositoryWithTypedId(Of ,))).Use(GetType(RepositoryWithTypedId(Of ,))) 
     [For](GetType(INHibernateRepositoryWithTypedId(Of ,))).Use(GetType(NHibernateRepositoryWithTypedId(Of ,))) 
    End Sub 

    Private Sub AddCustomRepositories() 
     Scan(AddressOf SetupCustomRepositories) 
    End Sub 

    Private Shared Sub SetupCustomRepositories(ByVal y As IAssemblyScanner) 
     y.Assembly("DebtRemedy.Core") 
     y.Assembly("DebtRemedy.Data") 
     y.WithDefaultConventions() 
    End Sub 

    Private Sub AddApplicationServices() 
     Scan(AddressOf SetupApplicationServices) 
    End Sub 

    Private Shared Sub SetupApplicationServices(ByVal y As IAssemblyScanner) 
     y.Assembly("DebtRemedy.ApplicationServices") 
     y.With(New FirstInterfaceConvention) 
    End Sub 

End Class 

Public Class FirstInterfaceConvention 
    Implements ITypeScanner 

    Public Sub Process(ByVal type As Type, ByVal graph As PluginGraph) Implements ITypeScanner.Process 
     If Not IsConcrete(type) Then 
      Exit Sub 
     End If 
     ''//only works on concrete types 
     Dim firstinterface = type.GetInterfaces().FirstOrDefault() 
     ''//grabs first interface 
     If firstinterface IsNot Nothing Then 
      graph.AddType(firstinterface, type) 
     Else 
      ''//registers type 
      ''//adds concrete types with no interfaces 
      graph.AddType(type) 
     End If 
    End Sub 
End Class 

Tôi đã thử cả hai ForRequestedType (mà tôi nghĩ bây giờ bị phản đối) và Đối. IRepository (Of T) sống trong SharpArch.Core.PersistenceSupport. Kho lưu trữ (Of T) sống trong SharpArch.Data.NHibernate.

lớp servicelocator My

Public Class StructureMapServiceLocator 
    Inherits ServiceLocatorImplBase 
    Private container As IContainer 

    Public Sub New(ByVal container As IContainer) 
     Me.container = container 
    End Sub 

    Protected Overloads Overrides Function DoGetInstance(ByVal serviceType As Type, ByVal key As String) As Object 
     Return If(String.IsNullOrEmpty(key), container.GetInstance(serviceType), container.GetInstance(serviceType, key)) 
    End Function 

    Protected Overloads Overrides Function DoGetAllInstances(ByVal serviceType As Type) As IEnumerable(Of Object) 
     Dim objList As New List(Of Object) 
     For Each obj As Object In container.GetAllInstances(serviceType) 
      objList.Add(obj) 
     Next 
     Return objList 
    End Function 
End Class 

lớp controllerfactory My

Public Class ServiceLocatorControllerFactory 
    Inherits DefaultControllerFactory 

    Protected Overloads Overrides Function GetControllerInstance(ByVal requestContext As RequestContext, ByVal controllerType As Type) As IController 
     If controllerType Is Nothing Then 
      Return Nothing 
     End If 

     Try 
      Return TryCast(ObjectFactory.GetInstance(controllerType), Controller) 
     Catch generatedExceptionName As StructureMapException 
      System.Diagnostics.Debug.WriteLine(ObjectFactory.WhatDoIHave()) 
      Throw 
     End Try 
    End Function 

End Class 

Các công cụ khởi trong global.asax tôi

Dim container As IContainer = New Container(New DefaultRegistry) 
ControllerBuilder.Current.SetControllerFactory(New ServiceLocatorControllerFactory()) 

ServiceLocator.SetLocatorProvider(Function() New StructureMapServiceLocator(container)) 

điều khiển thử nghiệm của tôi

Public Class DataCaptureController 
Inherits BaseController 

Private ReadOnly clientRepository As IClientRepository() 
Private ReadOnly pageRepository As IRepository(Of Page) 

Public Sub New(ByVal clientRepository As IClientRepository(), ByVal pageRepository As IRepository(Of Page)) 
    Check.Require(clientRepository IsNot Nothing, "clientRepository may not be null") 
    Check.Require(pageRepository IsNot Nothing, "pageRepository may not be null") 
    Me.clientRepository = clientRepository 
    Me.pageRepository = pageRepository 
End Sub 

Function Index() As ActionResult 
    Return View() 
End Function 

Trên đây hoạt động tốt khi tôi đưa ra tất cả mọi thứ để làm với pageRepository đó là IRepository (Of T).

Bất kỳ trợ giúp nào về điều này sẽ được đánh giá cao.

+1

Rất tiếc, tôi không thể giúp bạn khắc phục sự cố của bạn nhưng thật tốt khi thấy những người biết cách viết mã VB tốt . Phần lớn các câu hỏi của VB ở đây trên Stack Overflow khiến tôi tuyệt vọng. –

+0

IMHO bạn thực sự có thể đơn giản hóa câu hỏi này - chỉ hiển thị các dòng mã mà bạn đang cố gắng đăng ký các loại không thành công và thiết lập một vài dòng mã cố gắng lấy một thể hiện kiểu đó thông qua vùng chứa hoặc đối tượng . Nếu đăng ký không hoạt động, nó sẽ thất bại trong cùng một cách. –

Trả lời

1

Tôi đã gặp sự cố tương tự hôm qua với việc lập tức IRepository (Của MyEntity).

Tôi đã phải nêu rõ y.ConnectImplementationsToTypesClosing(GetType(IRepository(Of))) trong ủy quyền Quét để tạo các loại bản đồ StructureMap chung cho việc triển khai của chúng.

Như thế này:

Private Shared Sub SetupCustomRepositories(ByVal y As IAssemblyScanner) 
    y.Assembly("DebtRemedy.Core") 
    y.Assembly("DebtRemedy.Data") 
    y.WithDefaultConventions() 
    y.ConnectImplementationsToTypesClosing(GetType(Of)); 
End Sub 
1

Hãy chắc chắn rằng bạn chỉ tạo một container.

Tôi cũng đã chuyển đổi dự án C# từ Castle Windsor thành StructureMap. Dự án dựa trên CW ban đầu đã khởi tạo một Container trong Application_Start() (dự án MVC2) và truyền xung quanh nó cho cấu hình. Tôi giữ cách tiếp cận tương tự mà không cần suy nghĩ, kinda khi bạn dịch từ tiếng Tây Ban Nha sang tiếng Anh, và nó chỉ là xấu. :)

Điều gì đã xảy ra là tôi đã tạo ra một hộp chứa SM thứ hai. Container của StructureMap là tĩnh và vì vậy luôn có một "ở chế độ nền". Nếu bạn mới lên một container, bạn thực sự tạo ra một container thứ hai, độc lập. nếu bạn không cẩn thận, đôi khi bạn sẽ sử dụng một, đôi khi khác, và nhận được một lỗi của "Không có trường hợp mặc định" lỗi tại các điểm khác nhau khi bạn biết nó được xác định ..

Cách tôi bắt gặp nó là rằng tôi đã kết thúc việc viết mã với các cuộc gọi WhatDoIHave(), điều may mắn vì tôi đã lưu ý rằng đôi khi tôi thấy một thùng chứa được định cấu hình (thứ hai) và đôi khi tôi thấy một cái tĩnh (cái đầu tiên) chưa được cấu hình. Tên GUID khác nhau là giveaway.

Kiểm tra xem điều tương tự có xảy ra trong mã VB của bạn hay không.