Moles: Mole a ReadOnly Shared/Static Property - moles

How can I return a different value for MyList using Moles?
Given the following class:
Namespace Test
Public Class MyTestClass
Private Sub New()
End Sub
Public Shared ReadOnly MyList As New List(Of String)({"SomeValue"})
End Class
End NameSpace
I've tried to access the shared property from Test.Moles.MMyTestClass but MMyTestClass doesn't contain the member MyList. I also tried to add a behavior to return the value I want, but again, I'm not sure how to access the MyList from the test method.
Thanks!

Related

class access control: What if there is readonly access controller?

While I was using class, I found that some attributes, especially the ones which are boolean, are often read by other instances. For example,
class Node{
private:
int item;
bool visited;
public:
bool isVisited(){return visited;}
void bar(){
...
visited=true;
...
}
};
class Graph{
private:
vector<Node> nodes;
public:
void bar(int idx){
if(nodes[idx].isVidited()){
...
nodes[idx].foo();
...
}
}
}
In that case if visited is only changed by the methods of the class Node, then the access controller of the attribute visited shouldn't always be private in perspective of reading. What if there is an access controller 'readonly' that is opened to reading, closed to writing? I think that is useful when defining state attributes. Will there be any side effects?
Have you tried marking the Graph class as friend inside the Node class?
This facilitates accessing the private members of the Node class by the Graph class.
In some languages, there is getter/setter which works as an api of a private value.
It seems like a public value, but internally the methods control the private member variable, not the code with '=' operator itself.
//TYPESCRIPT
class Foo{
private _name:string
constructor(n:string){this._name=n}
get name(){return this._name}
//set name(n:string){this._name=n}
}
const foo=new Foo('Jack jack')
console.log(foo.name) //[LOG]: "Jack jack"
foo.name='hudson' //[ERR]: Cannot set property name of #<Foo> which has only a getter
The code above shows how a readonly property is set. There is only a getter which delivers exactly the same value of the private member variable '_name', but since setter is not defined, only the class itself can change the value and is not able to edit from outside of the class.

MVVM: list in viewmodel consists of entities but I don't think it's right to place logic in entity poco classes

I have a viewmodel and it exists out of entity framework classes (just plain classes). I Read on stackoverflow that it's okey to put an inotifypropertychanged in the model. So I did that in order not to have a lot of extra code.
So, now I have to perform an action when a property changes in one of my list items... the thing is, I can't react on this, in my viewmodel...
What do I do?
I have come across this issue once I started making larger projects with the MVVM pattern.
In the end I just shifted my INotifyPropertyChanged event calls to the ViewModel properties. I also decorated these properties with validation notification as that is where most of the validation that needs a user to react to will be held, any common elements can also be pulled out to a base ViewModel where relevant.
Another issue that you might come across as time goes by is where to put some of your processing logic. I used to have mine at the Model level, but then some of them required a bit closer interaction with the UI (validation reasons mainly), but if I put it in the ViewModel then I would have to have references to my repositories etc. In the end my ViewModels have access to another layer (a Service Layer) where this takes place. (A prime example for the use of this would be if you have a column in a database which is unique that you need to check when a user has created/modified data belonging to this column.)
Anyway, that is just a bit of extra information that I had to figure out shortly after the issue your currently having!
i fought with the best stategy for this for a while. I found that there are a number of different ways to do this.
First thing to note, if you add the property validation/notification directly to your model classes then the notifictaion and validation will happen when the class is created and for each object that gets created in observable collections, which in turn can cause performance issues or other challenges. So for that reason I moved my validation and notification into a "helper" partial class for the model.
So the model gets created through the Entity framework, lets say for an object called Job. I create public partial class called job as well. Here is an example (in vb, I can convert to C# if you need)
Partial Public Class job
Inherits ValidationBase
#Region "CONSTRUCTORS"
Public Sub New()
''default values
Me.FTC_Type = 4
Me.dtCreated = Now
Me.dtUpdated = Now
HasChanges = False
End Sub
Public Sub New(bValidate As Boolean)
PropertyValitaion(bValidate)
''default values
Me.FTC_Type = 4
Me.dtCreated = Now
Me.dtUpdated = Now
HasChanges = False
End Sub
Public ReadOnly Property DisplayPath
Get
Return "W" + idJob.ToString + ": " + chrTitle + " - " + client.chrCompany
End Get
End Property
Public ReadOnly Property SearchPath
Get
Return "W" + idJob.ToString + " " + chrTitle + " " + client.chrCompany + " " + chrContact
End Get
End Property
#End Region
#Region "VALIDATION FUNCTIONS"
Public Overrides Function Validate(validationContext As ComponentModel.DataAnnotations.ValidationContext) As IEnumerable(Of ComponentModel.DataAnnotations.ValidationResult)
Return MyBase.Validate(validationContext)
PropertyValitaion(True)
End Function
Public Sub PropertyValitaion(bAllProperties As Boolean, Optional sProperty As String = "")
'initialize validation helper
If bAllProperties OrElse sProperty = "chrTitle" Then
If String.IsNullOrEmpty(chrTitle) Then
AddError("chrTitle", "You must enter a Job Title")
Else
RemoveError("chrTitle")
End If
End If
End Sub
#End Region
End Class
So you can see that I can create other readonly properties (Like display title etc) and create my own custom validation that gets called when I want. THis validation uses the IDataErrorInfo for getting tied back into the UI. I have two constructors, one the calls the property validation and one that does not. That way I can control when it happens.
I created a ValidationBase class that my Objects partial class inhertis from. THis saves me from having to manually implement IdataErrorInfo and INotifyPropertyCHnaged in every partial class for every object.
Here is my validation base:
Imports System.ComponentModel
Imports System.Collections.Concurrent
Imports System.ComponentModel.DataAnnotations
Imports System.ComponentModel.DataAnnotations.Schema
Public Class ValidationBase
Implements IValidatableObject, IDataErrorInfo, INotifyPropertyChanged
#Region "DECLARATIONS"
Protected _propertyErrors As New Dictionary(Of String, String)
Protected _validationResults As New List(Of ValidationResult)
Public ReadOnly Property HasErrors() As Boolean
Get
Return (_propertyErrors.Count + _validationResults.Count) > 0
End Get
End Property
#End Region
#Region "IValidatableObject IMPLEMENTATION"
Public Overridable Function Validate(validationContext As ValidationContext) As IEnumerable(Of ValidationResult) Implements IValidatableObject.Validate
Return Nothing
End Function
#End Region
#Region "iDataError OBJECTS"
'Returns an error message
'In this case it is a general message, which is
'returned if the list contains elements of errors
Public ReadOnly Property [Error] As String Implements System.ComponentModel.IDataErrorInfo.Error
Get
If _propertyErrors.Count > 0 Then
Return "Object data is invalid"
Else
Return Nothing
End If
End Get
End Property
Default Public ReadOnly Property Item(ByVal columnName As String) As String Implements System.ComponentModel.IDataErrorInfo.Item
Get
If _propertyErrors.ContainsKey(columnName) Then
Return _propertyErrors(columnName).ToString
Else
Return Nothing
End If
End Get
End Property
#End Region
#Region "IDataError FUNCTIONS"
'Adds an error to the collection, if not already present
'with the same key
Protected Sub AddError(ByVal columnName As String, ByVal msg As String)
If Not _propertyErrors.ContainsKey(columnName) Then
_propertyErrors.Add(columnName, msg)
OnPropertyChanged(columnName)
End If
End Sub
'Removes an error from the collection, if present
Protected Sub RemoveError(ByVal columnName As String)
If _propertyErrors.ContainsKey(columnName) Then
_propertyErrors.Remove(columnName)
OnPropertyChanged(columnName)
End If
End Sub
Public Sub ClearErrors()
_propertyErrors.Clear()
End Sub
#End Region
#Region "INotifyPropertyChanged IMPLEMENTATION"
Public Event PropertyChanged(sender As Object, e As PropertyChangedEventArgs) Implements INotifyPropertyChanged.PropertyChanged
Public Overridable Sub OnPropertyChanged(ByVal propertyName As String)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End Sub
#End Region
End Class
SO i can't say this is the totally right way because there does not seem to be a clear best pratcie defined out there. But this works for me and I hope it can help you.

Access specifiers in class

I know that, normally, 'objects' of a class cannot access the private members. But in the function definition of a copy constructor, you use objects to access the private members members. How come?
eg:-
class Sample {int i,j;
public:
Sample(int a, int b)
{i=a;j=b;}
Sample(Sample &S)
{j=s.j;i=s.i;}
}
It is the same class. A different instance, but the same class.
private means that the member is only visible within the class - including other instances.

Entity Framework: Many-to-Many

I have the following scenario: A Doctor can have multiple Companions. A Companion can also have multiple Doctors. Here are my classses (minus the context):
Public Class Doctor
Public Property DoctorId As Integer
Public Property Regeration As Integer
Public Property Name As String
Public Property Actor As String
Public Property Companions As List(Of Companion)
End Class
Public Class Companion
Public Property CompanionId As Integer
Public Property Name As String
Public Property Actor As String
Public Property Doctors As List(Of Doctor)
End Class
Public Class DoctorViewModel
Public Property DoctorId As Integer
Public Property Actor As String
Public Property Companions As List(Of CompanionViewModel)
End Class
Public Class CompanionViewModel
Public Property Actor As String
End Class
I'm trying to fetch a singular Doctor with a list of companions who have travelled with him. This I can do quite simply, but I'm trying to shape the query to get only a few columns and not the entire entity. He is my bungled query - the X's are what I can't figure out.
Dim query = From d In context.Doctors
From c In context.Companions
Select New DoctorViewModel With {
.Actor = d.Actor,
.DoctorId = d.DoctorId,
.Companions = XXXXXXX}
EDIT: If I query:
(From d In Tardis.Doctors
Where d.Actor = "Tom Baker"
Select New DoctorViewModel With {.Actor = d.Actor, .Companions = d.Companions.Select(Function(c) New CompanionViewModel With {.Actor = c.Actor})}).SingleOrDefault
I get:
"Unable to cast the type 'System.Collections.Generic.IEnumerable1' to
type 'System.Collections.Generic.List1'. LINQ to Entities only
supports casting Entity Data Model primitive types."
Would it be considered nasty to ditch the ViewModel classes in the query and just get the stuff as an anonymous type, then pass this to a constuctor in a ViewModel (my models have a whack of functions that are needed) and fill the class like this?
It probably would be not only okay but much more readable (aka maintainable) as well. Especially since the query wouldn't return an anonymous type, it would return an IQueryable
Solved! I've spent days on this! Trick was to change the List inside the Doctor ViewModel to IEnumerable(Of CompanionViewModel)

Dims being used by .class File

I have this and I want to use something similar to the way Java uses .class files to be able to call events and use them in my main code.
The problem is that I cannot get the .class file to use my Dims
Form1.vb:
Namespace LFS_External_Client
Public Class Form1
Inherits Form
Private OutGauge As OutGaugeInterface
Dim SpeedPref As String
Dim FuelCapacity As String
Dim Fuel As String
Public Sub New()
InitializeComponent()
End Sub
Private Sub Form1_Load() Handles MyBase.Load
Some Code
GetFuel()
End Sub
End Class
End Namespace
Then in the Dataproccer.vb (.class file):
Public Class DataProcesser
Public Sub GetFuel()
Some Code
Fuel = og.Fuel.ToString() * FuelCapacity
End Sub
End Class
Code was shortened but has all of the relevant and necessary parts.
If you want to use the actual variables from the form instead of passing them through the method calls, you would need to declare them public instead of using dim:
...
Private OutGauge As OutGaugeInterface
Public SpeedPref As String
Public FuelCapacity As String
Public Fuel As String
...
Dim FuelCapacity As String
Private Sub Form1_Load() Handles MyBase.Load
Some Code
DataProcesser.GetFuel(FuelCapacity)
End Sub
Public Shared Sub GetFuel(Byval FuelCapacity as string)
Some Code
Fuel = og.Fuel.ToString() * FuelCapacity
End Sub
Looking at the MSDN page for the Dim Statement.
It states:
Code outside a class, structure, or module must qualify a member
variable's name with the name of that class, structure, or module.
Code outside a procedure or block cannot refer to any local variables
within that procedure or block.
Also according to this MSDN article the default access level for the Dim Statement is Private at the Module Level.
So why not make GetFuel a function and pass the FuelCapacity in like #kcBeard states and return the Fuel value.
Private Sub Form1_Load() Handles MyBase.Load
Some Code
Fuel = DataProcesser.GetFuel(FuelCapacity)
End Sub
Public Shared Function GetFuel(Byval FuelCapacity as string) as string
Some Code
return og.Fuel.ToString() * FuelCapacity
End Function
You can make SpeedPref, FuelCapacity and Fuel public member variables, however a better approach would be to make them properties on the class with appropriate getters and setters. Dim just declares a variable. Please see the modified code sample below:
Form1.vb:
Namespace LFS_External_Client
Public Class Form1
Inherits Form
Private OutGauge As OutGaugeInterface
Private _SpeedPref As String
Private _FuelCapacity As String
Private _Fuel As String
Public Property SpeedPref
Get
return _SpeedPref
End Get
Set(value As String)
_SpeedPref = value
End Set
End Property
...
End Class
End Namespace