2015-10-12 3 views
0

Я пытаюсь реализовать Dependency Injection, используя единство контейнера в vb.netDependency Injection vb.net, используя единство

когда я делаю вызов метода решительность я получаю ошибку resolutionFaieldException

Постановление зависимости Failed , type = "Test.EmailSending", name = "PDFEmailSender". Исключение произошло во время: при разрешении.

Module Module1 

Private iemail As IErrorEmail 

Sub Main() 

    'Dim email As New Test.EmailSending(iemail) 
    'email.Email() 
    Dim unity As UnityContainer = New UnityContainer 
    unity.RegisterType(Of IErrorEmail, SQLErrorEmail)("SQLErrorEmail") 
    unity.RegisterType(Of IErrorEmail, GenericEmail)("GenericEmail") 
    unity.RegisterType(Of IErrorEmail, Emailsending)("Emailsending") 
    Dim email1 = unity.Resolve(Of EmailSending)("SQLErrorEmail") 
    email1.Email() 
End Sub 



End Module 

Интерфейс прост Ошибка электронной почты Интерфейс

Namespace InterfaceError 
Public Interface IErrorEmail 
    Function ErrorEmail() As Boolean 
End Interface 
End Namespace 

Я добавил два типа классов электронной почты, которые реализуют интерфейс IERROR

Imports InterfaceSender.InterfaceError 
Public Class SQLErrorEmail 
    Implements IErrorEmail 
    Private _SenderEmail As IErrorEmail 
    Public Sub New(SQLErrorEmail As IErrorEmail) 
     _SenderEmail = SQLErrorEmail 
    End Sub 
    Public Function ErrorEmail() As Boolean Implements IErrorEmail.ErrorEmail 
     Dim isemailed As Boolean = False 
     Try 
      Email() 
     Catch ex As Exception 
     End Try 
     Return isemailed 
    End Function 
    Public Shared Sub Email() 
     Console.WriteLine("SQL Error Email") 
     Console.ReadLine() 
    End Sub 
End Class 

выше класс ошибок SQL реализует ErrorEmail и записывает на консоль, что это электронная почта с ошибкой SQL.

Imports InterfaceSender.InterfaceError 
Public Class GenericEmail 
    Implements IerrorEmail 
    Private _SenderEmail As IErrorEmail 
    Public Sub New(GenericEmail As IErrorEmail) 
     _SenderEmail = GenericEmail 
    End Sub 
    Public Function SendEmail() As Boolean Implements IErrorEmail.ErrorEmail 
     Dim isemailed As Boolean = False 
     Try 
      Email() 
     Catch ex As Exception 

     End Try 
     Return isemailed 
    End Function 
    Public Shared Sub Email() 
     Console.WriteLine("Generic Error Email") 
     Console.ReadLine() 
    End Sub 
End Class 

выше класс реализует общую ошибку, которая наследует интерфейс IERROR и когда вызывается метод электронной почты он выдает выходной Genric электронной почты на консоль.

Imports Method.GenericEmail 
Imports Method.SQLErrorEmail 
Imports InterfaceSender.InterfaceError 
Public Class EmailSending 
    Private _Isender As IErrorEmail 
    Public Sub New(ByVal Email As IErrorEmail) 
     MyBase.New() 
     _Isender = Email 
    End Sub 
    Public Sub EmailSendingLogic() 
     Dim type As String = "SQL" 
     If type = "SQL" Then 
      Method.SQLErrorEmail.Email() 
     ElseIf type = "Generic" Then 
      Method.GenericEmail.Email() 
     End If 
    End Sub 
End Class 
+2

Вы сами зарегистрировали «EmailSending»? Потому что он не зарегистрирован в коде выше –

+0

Нет, я не попробовал – user1339913

+0

Каков граф объектов, который вы пытаетесь создать? Какую реализацию 'IErrorEmail' вы хотите ввести в' EmailSending'? Можете ли вы объяснить больше о том, что вы пытаетесь сделать? –

ответ

1

Итак, вы пытаетесь создать класс (EmailSending), который знает, который IErrorEmail использовать в зависимости от какой-то логики.

Во-первых, вам не нужно вводить IErrorEmail в конструкторы GenericEmail и SQLErrorEmail. Зачем ты это делаешь?

Вот как я вижу эти два класс должен выглядеть следующим образом:

Public Class SQLErrorEmail 
    Implements IErrorEmail 
    Public Sub New() 

    End Sub 
    Public Function ErrorEmail() As Boolean Implements IErrorEmail.ErrorEmail 
     Console.WriteLine("SQL Error Email") 
     Return True 
    End Function 

End Class 


Public Class GenericEmail 
    Implements IErrorEmail 

    Public Sub New() 

    End Sub 
    Public Function SendEmail() As Boolean Implements IErrorEmail.ErrorEmail 
     Console.WriteLine("Generic Error Email") 
     Return True 
    End Function 
End Class 

Тогда, поскольку EmailSending класса должен использовать как отправитель электронной почты (GenericEmail и SQLErrorEmail), вы должны инъекционные два IErrorEmail зависимости в него, как это:

Public Class EmailSending 
    Private ReadOnly m_GenericSender As IErrorEmail 
    Private ReadOnly m_SqlSender As IErrorEmail 
    Public Sub New(generic_sender As IErrorEmail, sql_sender As IErrorEmail) 
     m_GenericSender = generic_sender 
     m_SqlSender = sql_sender 
    End Sub 

    Public Sub EmailSendingLogic() 
     Dim type As String = "SQL" 
     If type = "SQL" Then 
      m_SqlSender.ErrorEmail() 
     ElseIf type = "Generic" Then 
      m_GenericSender.ErrorEmail() 
     End If 
    End Sub 
End Class 

Наконец, вот как вы бы зарегистрировать свой график объекта с помощью единицы:

Dim unity As UnityContainer = New UnityContainer 
unity.RegisterType(Of IErrorEmail, SQLErrorEmail)("SQLErrorEmail") 
unity.RegisterType(Of IErrorEmail, GenericEmail)("GenericEmail") 
unity.RegisterType(Of EmailSending)(
    New InjectionConstructor(
     New ResolvedParameter(Of IErrorEmail)("GenericEmail"), 
     New ResolvedParameter(Of IErrorEmail)("SQLErrorEmail"))) 

А вот как вы бы решить и использовать ваш EmailSending:

Dim email1 = unity.Resolve(Of EmailSending)() 

email1.EmailSendingLogic() 

Другой способ сделать это (я считаю, что лучше с точки зрения дизайна), чтобы создать abstract factory, который создает соответствующее IErrorEmail реализация на основе некоторой логики (например, тип).Вот пример:

Public Interface IErrorEmailFactory 
    Function Create(type As String) As IErrorEmail 
End Interface 

Public Class ErrorEmailFactory 
    Implements IErrorEmailFactory 

    Public Function Create(type As String) As IErrorEmail Implements IErrorEmailFactory.Create 
     If type = "SQL" Then 
      Return New SQLErrorEmail() 
     ElseIf type = "Generic" Then 
      Return New GenericEmail() 
     End If 
    End Function 
End Class 

И потом, вы бы впрыснуть IErrorEmailFactory в EmailSending так:

Public Class EmailSending 
    Private ReadOnly m_Factory As IErrorEmailFactory 

    Public Sub New(factory As IErrorEmailFactory) 
     m_Factory = factory 
    End Sub 

    Public Sub EmailSendingLogic() 
     Dim type As String = "SQL" 

     Dim error_email = m_Factory.Create(type) 

     error_email.ErrorEmail() 

    End Sub 
End Class 

И тогда вы бы зарегистрировать его и использовать его как это:

Dim unity As UnityContainer = New UnityContainer 

unity.RegisterType(Of IErrorEmailFactory, ErrorEmailFactory)() 

Dim email1 = unity.Resolve(Of EmailSending)() 

email1.EmailSendingLogic() 
+0

Вы спасатель жизни !!!!. Отличное объяснение. Является ли интерфейс ierrorEmail, созданный методом RegisterType или методом разрешения единицы. – user1339913

+0

'RegisterType' просто создает сопоставление между интерфейсом и классом (есть и другие типы отображений). 'Resolve' используется для фактического создания объекта (или графа объектов). Надеюсь, я правильно понял ваш вопрос. –