Structuremap Open Generic named instances - c#

I must do the following:
var someType = ObjectFactory.GetNamedInstance("myNamedInstance");
where someType can be any implementation of ICommand.
so I registered some of them:
For(typeof(ICommand<>)).Use(typeof(Command1)).Named("myNamedInstance1");
For(typeof(ICommand<>)).Use(typeof(Command2)).Named("myNamedInstance2");
is there a way to do this in StructureMap, because GetNamedInstance requires the type parameter which I don3t know until runtime.?

(For this, I'm assuming you created ICommand<T>)
This doesn't actually make any sense... think of the line:
//where aString is either myNamedInstance1 or myNamedInstance2
var someType = ObjectFactory.GetNamedInstance(aString);
Now assume that you are not going to use var, and instead the actual type. What would you put there that could compile? That is, what type can someType possibly be other than object?
Also, remember that ICommand<string> and ICommand<int> are both constructed types from ICommand<T>, but are not otherwise related - they have no common base type other than object.
If you don't the type until runtime, generics are not going to help a bunch - instead make your ICommand<T> inherit from some common interface - like ICommandBase - that has the methods you actually need.
However, if you just don't know the type in that method, you can push the unknown "up" in the compile by making the method containing that generic:
public void Execute<T>( string commandName)
{
var someType = ObjectFactory.GetNamedInstance<ICommand<T>>(commandName);
someType.Execute();
}
Now the caller of execute needs the type param... but again you could push that up. Notice that eventually you'll need the type parameter.

Related

The type T must be a reference type in order to use it as parameter while using interface

I got the error for the below code
public static Moq.Mock<T> CreateInstanceOfIMock<T>() {
return new Moq.Mock<T>();
}
I have solved the error it by using referred class type. See this below code
public static Moq.Mock<T> CreateInstanceOfIMock<T>() where T : class
{
return new Moq.Mock<T>();
}
Now I want to move this var mockColorsRepository = new Moq.Mock<IColorsRepository>(); code into common code by using generics. here IColorsRepository is an interface. So I made an interface reference for T instead of class like this below code
public static Moq.Mock<T> CreateInstanceOfIMock<T>() where T : interface
{
return new Moq.Mock<T>();
}
But am getting The type T must be a reference type in order to use it as parameter error. How can I refer interface instead of class to T. How can I achieve this?
class and struct in generic type constaints do not mean the same thing as the class and struct declarations that are used to declare class or struct types. Instead, they only restrict whether a generic type argument is a reference type (class), or a value type (struct).
So when you do where T : class you are not saying that T needs to be a class, you are saying that T needs to be a reference type. Similarly struct for value types.
Interfaces on their own do not have this property, so an interface can be implemented by both a reference type and a value type. As such, restricting your type to be of an interface does not really make sense there.
In your case, Moq requires you to pass a reference type, so you need to transitively carry over that type constraint in all your helper methods:
public static Moq.Mock<T> CreateInstanceOfIMock<T>()
where T : class
{
return new Moq.Mock<T>();
}
That’s all you need to do to create a mock of any valid type. You can use it with an interface using CreateInstanceOfIMock<IColorsRepository>() or any other type.
Of course, at that point, the method does not really make that much sense since it does not give you any benefit over just instantiating the mock yourself.
There's no generic constraint in C# to enforce that a type argument is an interface. But where T : class is really "where T is a reference type" - it includes interfaces.
If you wanted to enforce that T is an interface rather than a class, you could perform an execution-time check using typeof(T) within the method, but in this case it sounds like you don't really need to constrain it to be an interface.
I'm not sure that the "helper" method is particularly useful though - if you compare:
var mock = Helper.CreateInstanceOfIMock<Foo>();
and
var mock = new Moq.Mock<Foo>();
or even (unless you have Mock<T> as another type somewhere) just a using Moq; directive and
var mock = new Mock<T>();
The latter seems just as readable and shorter... it makes sense if you're going to add more logic in your method, but if it's only ever going to call the constructor, I don't think I'd bother with it.

Better Solution to find all classes which inherit from a baseclass (and interface) and return a list not List<System.Type> but List<Interface>

Maybe my brain is not working properly and i cant see the forest because of the trees ...
Currently I have a class called CheckManager which searches the current assembly for a certain type called UserControlBaseCheck which is declared in a separate library. (this works fine)
I do have a variable AllChecks of type SortedDictionary<IBaseCheck, UserControlBaseCheck> (and a custom IComparer class which know's how to sort IBaseCheck).
This variable AllChecks is used to populate a Stack. The stack is then worked through by a User, once it is depleted, it get's filled again with new instances of all classes inside the AllChecks variable. And the whole game starts again.
Currently i solved it this way:
//declaration of my container with all checks
private static SortedDictionary<IBaseCheck, UserControlBaseCheck> AllChecks =
new SortedDictionary<IBaseCheck, UserControlBaseCheck>(new Comparer());
// this is how i call the method to find all classes which inherit from the type
FindDerivedTypes(Assembly.GetExecutingAssembly(), typeof(UserControlBaseCheck));
//this is the definition... it seems to me bit odd that I have to use the Activator
//and create an instance and cast it to the interface just to do
//what i want to do...
//is there any other / easier / better way of doing so?
public static IList<IBaseCheck> FindDerivedTypes(Assembly assembly,Type baseType)
{
//FYI: until the '.Select' I get a list of type List<System.Type>
List<IBaseCheck> o = assembly.GetTypes()
.Where(t => t != baseType && baseType.IsAssignableFrom(t))
.Select(type => Activator.CreateInstance(type) as IBaseCheck)
.ToList();
return o;
}
i find it odd that I have to create first an instance of the type just to use/convert it to an interface. Why can't i just do: .Select(x=> x as IBaseCheck) I mean i have already a list with object of type List<System.Type> and it seems to me bit overkill what i am doing just to get my list of type IBaseCheck (List<IBaseCheck>)
Why can't I just do: .Select(x=> x as IBaseCheck)
Because x is an instance of the System.Type type, not your UserControlBaseCheck type.
It's important to understand that, when you use reflection, you are getting the metadata for the types. I.e. you are getting data that describes your types, not the types themselves. The System.Type type is one such kind of data. It is a runtime object that describes the types you declare. It is not those actual types, and it's definitely not an instance of those types.
Consider the trivial code example:
namespace ExampleNamespace
{
class A { }
}
There are many different ways of getting the System.Type that represents that type:
Type type1 = Assembly.GetType("ExampleNamespace.A"),
type2 = typeof(A),
type3 = (new A()).GetType();
But note that in the above, all three variables wind up with the same instance of System.Type. I.e. the instance that describes that type A.
Note also in the last assignment, to the variable type3, a new instance of A is being created. I.e. you can ask an instance for the information about its own type. But what's returned is not, of course, that instance. It's something completely different: the instance of System.Type describing the type of that instance of A.
So back to your example…
You're using reflection to search for instances of specific System.Type objects. These instances give you enough information to figure out which ones implement some base class (or even an interface, if you wanted). But since you want an actual instance of that class, you need to explicitly ask for one.
Just as you can't do this:
A a = typeof(A);
You also can't do this:
IBaseCheck baseCheck = typeof(UserControlBaseCheck);
Instead, you need to do this:
IBaseCheck baseCheck = new UserControlBaseCheck();
And the way that's done via reflection (well, one way anyway) is to call the Activator.CreateInstance() method.

Is it possible to have non-generic method return generic type?

In Java I can easily write:
public interface MyInterface<T extends Object>
and then have a method which determine the T at runtime like:
public MyInterface<?> DetermineObjectAtRuntime()
But in C# where <?> is not available and I need to call the method with type; which means I need to know the type before hand.
Is it possible to return generics type from non-generic method?
If not, how can I work out the type to call such generic method if I have an object instance with that type?
For people who are not sure what this is for - I have a set of data structures which are using different enums as field indexers. All the messages extends from a common generic interface with that enum as type variable. Now I need to work out a method which deserialize all different types of messages from a byte[] array.
In C#, which does not have type erasure, there are several ways to work around not knowing a type argument at compile-time:
Non-generic subset: If it happens to be the case that the methods of MyInterface<T> that you need don't involve T, then you can extract that portion of the interface into a base interface and return the base interface instead.
Pro: No runtime type shenanigans.
Con: Modifies the type (moving methods to a new base interface), breaking binary compatibility.
Type checking wrapper: Make a RuntimeTypeCheckedMyInterface<T> class that implements MyInterface<object> by delegating to a MyInterface<T> after type checking. Have the method return a MyInterface<object>, created by wrapping the MyInterface<whatever> inside a RuntimeTypeCheckedMyInterface.
Pro: Works with any existing interface type, without modifying it.
Con: Introduces "does T=object really mean object, or does it mean unknown type"? ambiguity.
Manual type erasure: Make a variant of MyInterface<T> that doesn't have a T like MyInterfaceOfUnknownType. Make MyInterface<T> inherit from MyInterfaceOfUnknownType. Have your method return MyInterfaceOfUnknownType.
Pro: Acts basically identical to Java, with MyInterfaceOfUnknownType = MyInterface<?>.
Con: Pollutes MyInterface<T> with non-generic methods. When the methods differ only by return type you have to disambiguate with a name change. Modifies the type (breaking source and binary compatibility).
Screw the types: Have the method return object or dynamic. Cast conditionally and appropriately.
Pro: Initially easy to do.
Con: Harder to maintain.
"But in C# where '< ? >' is not available and I need to call the method with type; which means I need to know the type before hand."
You can use dynamic instead of <T> for example:
dynamic Foo (dynamic Input) {return Input;}
The compiler determines the type at runtime.
In C#, you can have generic methods:
class Foo<X>
{
public T DoSomethingFunky<T>( ... )
{
...
}
}
But there's no way to have a wildcard type — a big fail in C#. It would be very useful in a lot of situations where you that it is a Widget<T> but you don't care about the particulars of T.
For instance, WCF throws FaultException<T>, where the various flavors of T are service specific. There's no way to catch something like FaultException<*> without simply catching the base Exception class and using reflection to inspect the caught exception to see if it's an interesting T. This prevents handling service faults in a generic way.
I believe the reason is that a concrete generic class (Widget<int>) are not really subtypes of the generic class (Widget<T>) it "inherits" from. The generic class is simply used as a template to compile a new specific class.
The one thing you could do, is have your generic template (Widget<T>) inherit from a non-generic base class (Widget) and have your method return that:
class AbstractWidget { ... }
class Widget<T> : AbstractWidget { ... }
.
.
.
public Widget GetGeneric Widget()
{
/* flavor determinated at runtime */
}
It's incumbent upon the caller to decide what to do with its Widget.
Another way is to add an extension
public static class MyExtensions
{
public static T As<T>(this object obj)
{
return (T)obj;
}
}
the above will provide you a .As() method

How to declare variable for open generic type? Possible?

Is there a way to declare a vaiable for an open generic type?
Given: There is a generic class Logger that users get from a factory method. Is there a way to have a variable that can hold ANY logger?
Right now Logger inherits from Logger ONLY for being able to declare a variable for an instance without caring what type is logged there.
I use MEF, and in the exports I can use a syntax like [Export(typeof(Logger<>))] to export a generic type... (specifying the exact type on import) so there is some support for open types (at least in typeof). What I need now is a syntax like
Logger<> Logger { get; set; }
Any possibility to do something like that? This particular syntax gets me "Type needed".
If Logger's type parameter is covariant, i.e., if it is declared with an out modifier, then you can just use Logger<object>.
IEnumerable<object> = new List<string>; // this works, because IEnumerable is covariant
If Logger's type parameter is not covariant, i.e., if you use it as an input parameter somewhere, e.g. Log(T dataToLog), then implementing a common interface (or using a common base class) seems to be the only way to achieve your goal.

Initialize and scope a generic abstract class

I have the following code
var dataCollection;
if (ViewBag.WageType.ToLower() == "perm")
{
dataCollection = ViewBag.PermWageIndex;
}
else if(ViewBag.WageType.ToLower() == "trial")
{
dataCollection = ViewBag.TrialWageIndex;
}
The return type can be AbstractClass<Concrete1> or AbstractClass<Concrete2>. I must initialize the var at declaration. But, this means I lose the scope I desire. How can I modify this code to allow dynamic dataCollections without depending on the ViewBag?
You might be able to make AbstractClass<> implement the interface IAbstractClass and then make that the common type.
Whether this will work or not depends exactly which members the return type needs to access. Obviously, it won't be able to refer to any of the generically typed members, but that wouldn't make much sense anyway, since I'm assuming the consumer shouldn't know what the generic parameter is anyway.
The only way solving this is by providing a base class or interface which is inherited/implemented by Concrete1 and Concrete2 so you can declare dataCollection as AbstractClass<ISomething>.
Var is not dynamic typing it is resolved at compile time. Therefore you can not declare a variable without assignment (var x;) because the compiler can not infer the type.
You can fall back to object or dynamic however you loose any type safety if you do so.

Categories