How to add serializable attribute to class that inherits from Exception - vb.net

I need to pass a custom exception class via .Net remoting but I am getting the error:
Type 'MyDll.Security.InvalidHashException' in Assembly 'MyDll, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.'
The InvalidHashException class is as follows:
Public Class InvalidHashException
Inherits Exception
Public Sub New()
End Sub
Public Sub New(ByVal message As String)
MyBase.New(message)
End Sub
Public Sub New(ByVal message As String, ByVal inner As Exception)
MyBase.New(message, inner)
End Sub
End Class
I understand that I have to add the <Serializable()> attribute to the class but then I get the following error:
System.Runtime.Serialization.SerializationException: 'The constructor to deserialize an object of type 'MyDll.Security.InvalidHashException' was not found.'
Can someone please help with how I would add a constructor that would help deserialize this object.
Many thanks.

Related

Type conversion error with Generic Interface

I'm trying to use interfaces for my Entities and Repositories but I can't seem to overcome a type conversion error. I have simplified the code to the basic minimum to reproduce this error.
'The entity interface
Public Interface IEntity
Property ID As Int32
End Interface
'A base class for new entities
Public MustInherit Class EntityBase
Implements IEntity
Public Property ID As Integer Implements IEntity.ID
End Class
'The repository interface
Public Interface IRepository(Of IEntity)
Function Load(ID As Int32) As IEntity
End Interface
'The base class for the repository
Public Class RepositoryBase(Of IEntity)
Implements IRepository(Of IEntity)
Public Overridable Function Load(ID As Integer) As IEntity Implements IRepository(Of IEntity).Load
Throw New NotImplementedException()
End Function
End Class
'An object using the entities base class
Public Class Person
Inherits EntityBase
Property Name As String
End Class
'An object using the repository base class
Public Class PersonRepository
Inherits RepositoryBase(Of Person)
Public Overrides Function Load(ID As Integer) As Person
Dim myPerson As New Person
'Do stuff for loading a Person
Return myPerson
End Function
End Class
'And here is some code to execute this all
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim PersonRepo As New PersonRepository
Dim TestWithType As IRepository(Of IEntity)
TestWithType = PersonRepo '<-- error goes here
End Sub
End Class
Intellisense doesn't give any error. The error only pops up when executing the code. The exact error is in Dutch:
Kan een object van het type Generic_Interface_test.PersonRepository
niet converteren naar het type
Generic_Interface_test.IRepository`1[Generic_Interface_test.IEntity].
So the PersonRepository cannot be converted to an IRepository type. But the PersonRepository class is based on the RepositoryBase which implements the IRepository interface.
What am I doing wrong here? In my final solution I want to drop my repositories into a dictionary but that seems impossible due to this error.
Update 1: The problem seems to be in the IEntity part. IRepository(Of IEntity) != IRepository(Of Person) while Person = IEntity.
Is there any way to create a list like List(Of IRepository(Of IEntity)) that actually works?
Update 2: I like the animal example of Tim so I will try to explain my question with animals.
Assume I have an interface IAnimal that I will use in another interface IRepository(Of IAnimal). For this type I will create a list Animals = List(Of IRepository(Of IAnimal)) where I can store repositories for all animals. Now I will create a class Lion based on the IAnimal interface and create a repository LionRepo based on IRepository(Of Lion). When I try to store LionRepo into Animals it fails because it expects IRepository(Of IAnimal) while my LionRepo is actually IRepository(Of Lion). But since Lion is based on IAnimal shouldn't this suppose to be working?

Logging errors and events, best practice?

I'm currently developing a 3-tier application and now I have come to logging, I am curios as to the best practices. Below is my interface and model for a LogEntry, I then implement that in a service called JsonLogService which serializes the entries and stores them in the file system.
Public Interface ILogService
Sub Log(logEntry As LogEntry)
Sub Log(source As String, type As LogEntryType, message As String)
Sub Log(source As String, type As LogEntryType, format As String, ParamArray arguments() As Object)
End Interface
Public Enum LogEntryType
Information
Warning
[Error]
Debug
End Enum
Public Class LogEntry
Public Property Source As String
Public Property Type As LogEntryType
Public Property Message As String
Public Property LoggedAt As Date = DateTime.Now
Public Sub New()
End Sub
Public Sub Now(source As String, type As LogEntryType, message As String)
Me.Source = source
Me.Type =
Me.Message = message
End Sub
Public Sub New(source As String, type As LogEntryType, format As String, ParamArray arguments() As Object)
Me.Source = source
Me.Type = type
Me.Message = String.Format(format, arguments)
End Sub
I'm currently using this service in my managers to log when events happen which works well, but now I am unsure how to implement this for catching errors.
Does it actually make sense to catch errors in my managers methods because surely my tests should prevent any errors from happening there?

How to cast object of type 'especific' to type 'FileHelpers.Events.INotifyRead in Multirecording

I'm trying to centralize all formatting and conversion rule in a single class especific. Using the interface INotifyRead(Of T As Class). When I implement the methods BeforeRead/AfterRead throws an exception: Unable to cast object of type 'Especific' to type 'FileHelpers.Events.INotifyRead`1[System.Object]'.
Below my code.
Using engine As New MultiRecordEngine(New RecordTypeSelector(AddressOf CifraRecordTypeSelector),
GetType(RemessaRegistroCliente),
GetType(RemessaRegistroContrato))
Dim records = engine.ReadFile(_camArquivo)
End Using
Public NotInheritable Class RemessaRegistroCliente
Implements INotifyRead(Of RemessaRegistroCliente)
Public Sub AfterRead(e As AfterReadEventArgs(Of RemessaRegistroCliente)) Implements INotifyRead(Of RemessaRegistroCliente).AfterRead
End Sub
Public Sub BeforeRead(e As BeforeReadEventArgs(Of RemessaRegistroCliente)) Implements INotifyRead(Of RemessaRegistroCliente).BeforeRead
End Sub
End Class
Public NotInheritable Class RemessaRegistroContrato
Implements INotifyRead(Of RemessaRegistroContrato)
Public Sub AfterRead(e As AfterReadEventArgs(Of RemessaRegistroContrato)) Implements INotifyRead(Of RemessaRegistroContrato).AfterRead
End Sub
Public Sub BeforeRead(e As BeforeReadEventArgs(Of RemessaRegistroContrato)) Implements INotifyRead(Of RemessaRegistroContrato).BeforeRead
End Sub
End Class
Since MultiRecordEngine has no generic version, you cannot implement the generic INotifyRead(Of T) to handle events. Instead, assign delegates to the engine.
Sub Main()
Using engine As New MultiRecordEngine(New RecordTypeSelector(AddressOf CifraRecordTypeSelector),
GetType(RemessaRegistroCliente),
GetType(RemessaRegistroContrato))
AddHandler engine.BeforeReadRecord, AddressOf BeforeReadRecordHandler
End Using
End Sub
Private Sub BeforeReadRecordHandler(ByVal engine As EngineBase, ByVal e As BeforeReadEventArgs(Of Object))
End Sub
You'll also need to modify your classes to remove the generic interfaces:
Public NotInheritable Class RemessaRegistroCliente
'your fields
End Class
Public NotInheritable Class RemessaRegistroContrato
'your fields
End Class

How to create a class that one of its object is in the type of another class in VB?

Following is my code
Class LIVandOSA
Public LIV_ As String
Public OSA_ As String
End Class
Class TestUnitID
Public SMPSdata As LIVandOSA
Public SMdata As LIVandOSA
Public COATEDBARdata As LIVandOSA
Public CLCLdata As LIVandOSA
Public Sub New(ByVal s As String)
SMPSdata.LIV_ = s
End Sub
End Class
In the main program, I wrote the following code to create a list of TestUnitID and add some element into it.
Dim a As New List(Of TestUnitID)
a.Add(New TestUnitID("a1.csv"))
a.Add(New TestUnitID("a2.csv"))
TextBox1.Text = a(0).SMPSdata.LIV_
But when I try to compile it, it gives me the following error
An unhandled exception of type 'System.NullReferenceException' occurred in WindowsApplication1.exe
Additional information: Object reference not set to an instance of an object.
And the error cursor was pointing to the line SMPSdata.LIV_(s)
How should I fix this error?
The error is self-explanatory, you haven't initialized that object.
Since you are in the constructor it is a good place to initialize fields and properties:
Class TestUnitID
Public SMPSdata As LIVandOSA
Public SMdata As LIVandOSA
Public COATEDBARdata As LIVandOSA
Public CLCLdata As LIVandOSA
Public Sub New(ByVal s As String)
Me.SMPSdata = New LIVandOSA()
Me.SMdata = New LIVandOSA()
Me.COATEDBARdata = New LIVandOSA()
Me.CLCLdata = New LIVandOSA()
SMPSdata.LIV_(s)
End Sub
End Class
You should have initiate it before using the object, therefor you can use
Me.SMPSdata = New LIVandOSA()
...
to create a new object

Using Views with non-default constructors in Prism

Afternoon,
I'm struggling at the moment to work out how I can create a view which requires a non default constructor (ie a constructor that requires input),
Public Class Bootstrapper
Inherits UnityBootstrapper
Protected Overrides Function CreateShell() As System.Windows.DependencyObject
Return New LogReader_Modular.Windows.Shell()
End Function
Protected Overrides Sub InitializeShell()
MyBase.InitializeShell()
Application.Current.MainWindow = CType(Me.Shell, Window)
Application.Current.MainWindow.Show()
End Sub
Protected Overrides Sub ConfigureModuleCatalog()
MyBase.ConfigureModuleCatalog()
Dim moduleCatalog As ModuleCatalog = CType(Me.ModuleCatalog, ModuleCatalog)
moduleCatalog.AddModule(GetType(GridModule))
End Sub
....
....
Public Class GridModule
Implements IModule
Private ReadOnly regionManager As IRegionManager
Public Sub Initialize() Implements IModule.Initialize
Try
regionManager.RegisterViewWithRegion("MainDockingRegion", GetType(Views.GridModuleView))
Catch ex As Exception
Trace.WriteLine(String.Format("An Error occured the error was {0}", ex.ToString))
End Try
End Sub
Public Sub New(ByVal regionManager As IRegionManager)
Try
Me.regionManager = regionManager
Catch ex As Exception
Trace.WriteLine(String.Format("An Error occured the error was {0}", ex.ToString))
End Try
End Sub
End Class
my issue is I want to pass in constructor values to GridModuleView, as its not really instantiated as such here, i dont really understand how I can pass in the values, any help with this would be appreciated as I've been looking at this for a few days now. EDIT * the data im wanting to pass in is coming from the shell and not the view, which is why i pasted the bootstrapper
Thanks
Tom.
You could use the RegionManager.RegisterViewWithRegion(IRegionManager, String, Func(Object)) method instead of the RegionManager.RegisterViewWithRegion(IRegionManager, String, Type) method and then pass the input from the shell to the GridModule.