Ninject dynamic multiple constructor arguments - vb.net

I have been implementing Dependency Injection into an existing Winforms project and it has been going well so far, however I want to generalise the calling of the Forms, specifically the varying quantity of constructor parameters.
My code is as follows:
Public Shared Function GetForm(formObject As BaseObject, _
parameters As Dictionary(Of String, Object)) As Form
Select Case formObject.GetType()
Case GetType(Production.Task)
Return SMKernel.Kernel.Get(Of Forms.Production.Domain.ManageTask) _
(New Parameters.ConstructorArgument() _
{New Parameters.ConstructorArgument("task", _
CType(formObject, Production.RequiredTask))})
End Select
End Function
This works fine, the interface(s) are injected correctly, the constructor parameter "task" is populated and the Form works as expected.
As you can see I have a Dictionary that can contain several parameters which I need to add to the ConstructorArgument part of the Get method. Looking at the IntelliSense, I should be able to pass in an array of ConstructorArgument objects, however no matter what I have tried, it doesn't seem to work for one reason or another.
How do you accomplish this in Ninject if it is at all possible. If this way isn't possible, how can you pass multiple parameters into a Form's constructor via Ninject?

Use the already provided ResolutionExtensions
public static T Get<T>(this IResolutionRoot root, params IParameter[] parameters)
Then combine it with LINQ
Kernel.Get(parameters.Select(kvp => new ConstructorArgument(kvp.Key, kvp.Value)).ToArray())
Provide more details and we might give you are more elegant approach.

Related

best matching overloaded method is not being called

I have the following methods:
Public Function RenderRateTable() As String
Private Function RenderRateTable(ToddVersionedObject As ToddVersionedObject,
FieldInfo As FieldInfo) As String
Private Function RenderRateTable(ArrayIndexes As List(Of ArrayIndexesAttribute.ArrayIndex),
ThreeDimensionalArray As ThreeDimensionalDecimalArrayType) As String
Private Function RenderRateTable(ArrayIndexes As List(Of ArrayIndexesAttribute.ArrayIndex),
TwoDimensionalArray As ArrayOfDecimalArraysType) As String
Note that the types that I'm overloading (ArrayOfDecimalArraysType, ThreeDimensionalDecimalArrayType) are not classes that inherit from the same base class. They are different structures that don't inherit from anything. They were written by someone else and I can't change them.
When I call it from within the same class like this
Dim MyThreeDimensionalDecimalArrayType As ThreeDimensionalDecimalArrayType
RenderRateTable(MyArrayIndexes, CType(MyThreeDimensionalDecimalArrayType, Object))
it doesn't go to the right method. It just goes to RenderRateTable().
What's even stranger is, the call is made with two arguments (parameters), but these are (ignored?) and it calls a method that takes no parameters and no run-time error is thrown!
I have Option Strict Off and the variable I'm passing to the parameter ThreeDimensionalArray is of type Object.
I'm trying to get it to where I have a bunch of overloads and it picks the right method based on the type of the Object passed.
Polymorphic method calling instead of an Select Case statement. I hate conditional blocks like that.
UPDATE
I got the code working by declaring the overloads Public, but I still don't understand:
Why the dispatcher wouldn't find the right Private method when the
call is within the same class.
Why the dispatcher would call a method with no parameters when the call is made with 2 parameters, and not throw an error.
You have RenderRateTable() as Public and the rest as Private, which will prevent it from being able to use the correct overload when called from outside the class.
It is very likely that Option Strict On would have pointed out that as a problem: I recommend that you use it to make your programming endeavours easier :)

Injection of class with multiple constructors

Resolving a class that has multiple constructors with NInject doesn't seem to work.
public class Class1 : IClass
{
public Class1(int param) {...}
public Class1(int param2, string param3) { .. }
}
the following doesn’t seem to work:
IClass1 instance =
IocContainer.Get<IClass>(With.Parameters.ConstructorArgument(“param”, 1));
The hook in the module is simple, and worked before I added the extra constructor:
Bind().To();
The reason that it doesn't work is that manually supplied .ctor arguments are not considered in the .ctor selection process. The .ctors are scored according to how many parameters they have of which there is a binding on the parameter type. During activation, the manually supplied .ctor arguments are applied. Since you don't have bindings on int or string, they are not scored. You can force a scoring by adding the [Inject] attribute to the .ctor you wish to use.
The problem you're having is that Ninject selects .ctors based on the number of bound parameters available to it. That means that Ninject fundamentally doesn't understand overloading.
You can work around this problem by using the .ToConstructor() function in your bindings and combining it with the .Named() function. That lets you create multiple bindings for the same class to different constructors with different names. It's a little kludgy, but it works.
I maintain my own software development blog so this ended up being a post on it. If you want some example code and a little more explanation you should check it out.
http://www.nephandus.com/2013/05/10/overloading-ninject/

Moq, VB, HttpResponseBase and Headers

I'm in the process of writing a heap of tests around some custom controllers using Moq in VB. Up until now, I've not had to deal with VB Lambda shortcomings since I've only moqed properties or methods.
That is until this morning when I try also running integration tests using Cassini against my code. I had code to add headers using Response.Headers.Add. I did this so I could easily get the headers collection in unit tests using Moq(Of HttpResponseBase) and a SetupGet for Headers->NameValueCollection. Of course, the code chokes in anything other than IIS7 in Integrated Pipeline mode.
So, I changed my code to use Response.AddHeader, which means my unit tests fail. And since I'm in VB, I can' see a sane way to map the call to AddHeader to the Headers collection since Function() needs a return value in VB.
I see a few entries here about Moq and VB, but no one really has the problem of mapping Subs to something else in Moq.
Has anyone tackled this particular situation in VB using Moq?
Ugh. Why do the solutions always become apparently AFTER you post. :-)
This is ugly, but it works.
Subclass HttpResponseBase.
Mock that and set the CallBase to True.
Then override Add/AppendHeader to do Headers.Add. Now you catch any variation people use in code as they all fall into Response.Headers collection. The realy code works regardless of which method you use.
Not as clean as just Moqing Add/Append in C# with callbacks, but it does work.
Dim response As New Mock(Of CustomHttpResponse)
response.SetupGet(Function(r As HttpResponseBase) r.Headers).Returns(New NameValueCollection)
response.CallBase = True
Public Class CustomHttpResponse
Inherits HttpResponseBase
Public Overrides Sub AddHeader(ByVal name As String, ByVal value As String)
Me.Headers.Add(name, value)
End Sub
Public Overrides Sub AppendHeader(ByVal name As String, ByVal value As String)
Me.Headers.Add(name, value)
End Sub
End Class

Linq To SQL DAL and lookup data source

I am learning linq to sql and I am trying to setup a lookup combo box in my web page. I was using a linq data source but I then moved my linqtosql code to it's own class library for my DAL dll (took out of app_code folder). So, I am converting the page code to be able to still have lookups driven now by a biz object.
Here's what I have done in my biz layer...
Public Class KosherTypes
Public Shared Function GetKosherTypes() As List(Of KosherTypeLookup)
Dim db As New DBDataContext
Dim types = From kt In db.KosherTypes _
Where kt.IsDeleted = False _
Order By kt.Name _
Select New KosherTypeLookup With {.Name = kt.Name, .ID = kt.KosherTypeID}
Return types.ToList
End Function
End Class
I then setup an object data source and mapped it to this class.
I have a few questions as when I was doing internet searches I didn't find anyone that seemed to be doing this and yet I know lookup tables / combo boxes are common...
Did I totally just miss something and there are better way(s) to do this?
I went with returning a list but I could have returned an IEnumerable or IQueryable. In my reading it seemed IQueryable had more functionality for linq to sql but since I am returning a simple two column list then I only need to return an IEnumerable or List. I went with a List since it's strongly typed. Did I make a good decision? AKA - Should I just have returned and IEnumerable or perhaps gone with IQueryable?
Thanks!
I'll answer in reverse order:
I wouldn't use IQueryable outside of your repos / DAL for the simple reason that since execution is deferred, you lose control of what exactly is executed (i.e., an aribtrary function could be assigned as a delegate for WHERE), making maintenance and testing much harder. I don't see an issue with you returning an IEnumberable(Of KosherTypeLookup) though.
If the lookup is a static lookup that never or rarely changes, you might want to look at a way to cache the lookup after the first use, to avoid having to hit the db every time that box is called. It really depends on your expected load, though. As always, performance/load testing will highlight where you need to optimize.

Creating a function that uses a generic structure?

I am attempting to create a generic function that the students in my introductory VB .NET course can use to search a single dimension array of a structure.
My structure and array look like this:
Private Structure Survey
Dim idInteger As Integer
Dim membersInteger As Integer
Dim incomeInteger As Integer
Dim stateString As String
Dim belowPovertyLevelBoolean As Boolean
End Structure
Private incomeSurvey(199) As Survey
My generic function header looks like:
Private Function FindSurveyItem(Of xType As Structure)
(ByVal surveyIDInInt As Integer, ByVal surveyArrayIn() As xType) As Integer
??????
End Function
My call to the function looks like:
If FindSurveyItem(Of Survey)(CInt(idTextBox.Text), incomeSurvey) <> -1 Then
My question is: Is there a way to reference the individual structure fields in the array from inside the function? I was trying to make it generic so that the student could simply pass their array into the function - their structure may be named differently than mine and the field names may be different.
I suspect there are other ways to deal with this situation, but I was trying to keep it to just a simple single-dimension array of a structure. I don't think it is possible to do what I want, but I wondered what others thought.
Is there a way to reference the individual structure fields in the array from inside the function?
Generic instead of an array you need a collection type. Add LINQ Code:
Dim Surveys = From svys In xType
Where svys.idInteger = surveyIDInInt
Select svys
For Each rSurveys In svys
'''' Your Code
Next
This is rough answer fill in the details (I know imagine LINQ without SQL DB!!)
If you have a genric type parameter T you are only able to access members of instances of T that are known to exist at compile time. As every type derives from Object you have only the members of Object availiable - ToString(), GetType(), GetHashCode(), and Equals().
If you want to access other members you have to constrain what T is allowed to be. In your situation a interface would be the way to go. See MSDN for details.
You could also try to use reflection or check the actual type at runtime an perform a cast. The first is hard to impossible to do if you do not know much about the types you will get. And the later requires you to know possible types at compiletime and will not work in your situation, too.
Another way might be to pass a delegate to the search method that performs the actual comparison.
What you're looking for are predicates, if using ,net 3.5
dim arr() as structure
Array.Find(arr, function(item)(item.MyMember = MemberToMatch))
More combersome in earlier versions, see here for more info
The point being, that your function would look very like an implementation of Array.Find (if you didn't want to use the function provided), and the students would need to write their own predicate function.
No, there isn't. You can't know the type at compile time, therefore you cannot access members of that type. You would need change from a structure to a class that must implement IComparable so that you can use CompareTo between the item you pass in and the array you are passing in.
Though it's not entirely clear what you are trying to do within your method so I'm guessing by the name of the method.
You can use reflection to get those fields, but in this case that wouldn't have much meaning. How would you know that the passed type has the field you're looking for? There are other problems with that code as well.
Instead, to do this I would normally create an interface for something like this that had a public ID property, and constrain my input to the function to implement that interface, or as others mentioned use a built-in feature in the clr.
But that may be ahead of where your students are. If you just want an example of a generic function, my suggestion is to show them a type-safe implementation of the old vb imediate if function:
Public Function IIf(Of T)(ByVal Expression As Boolean, ByVal TruePart As T, ByVal FalsePart As T) AS T
If Expression Then Return TruePart Else Return FalsePart
End Function
Note that this is obsolete, too, as in VS2008 and beyond you can use the new If operator instead, which will work better with type inference and won't try to evaluate the expression that isn't returned.