I've got some legacy code to add unit testing to. I can add shims where necessary to classes that need instanciating, but some of the code uses static classes. I can't add a shim properly.
for example (simplified for clarity):
public static class DBHelper
{
public static ObservableCollection<Run> GetRuns()
{
ObservableCollection<Run> retval = new ObservableCollection<Run>();
using (AriaEntities DBC = new AriaEntities())
{
var res = DBC.Runs.OrderByDescending(x => x.Run_Number).Take(100).ToList();
retval = new ObservableCollection<Run>(res);
}
return retval;
}
}
I want to shim this method. if it was non static, I'd use:
using (ShimsContext.Create())
{
ShimDBHelper.AllInstances.GetRuns = (i) => { return FakeRunList(); };
...
}
But with a static I get "'DBHelper': static types cannot be used as parameters". If I remove the parameter, I get told that the delegate doesn't take 0 arguments.
Whats the syntax for a static class, if there is one?
Related
I have a generic class of two types, "MyClass<T,U>". Based on a parameter to the class constructor, I'd like to be able to set a "Func<T,U>" local variable in a class instance that can be called to efficiently invoke a static method with input type T and output type U. The work done on the input variable depends on the input type. Can this be done?
Here's some code I've been playing with...
namespace ConsoleApp {
public class MyClass<T, U> {
// First constructor. Pass in the worker function to use.
public MyClass(Func<T, U> doWork) {
_doWork = doWork;
}
// Second constructor. Pass in a variable indicating the worker function to use.
public MyClass(int workType) {
if (workType == 1) _doWork = Workers.Method1;
else if (workType == 2) _doWork = Workers.Method2;
else throw new Exception();
}
// User-callable method to do the work.
public U DoWork(T value) => _doWork(value);
// Private instance variable with the worker delegate.
private Func<T, U> _doWork;
}
public static class Workers {
public static ushort Method1(uint value) => (ushort)(value >> 2);
public static uint Method1(ulong value) => (uint)(value >> 1);
public static ushort Method2(uint value) => (ushort)(value >> 3);
public static uint Method2(ulong value) => (uint)(value >> 4);
}
public class Program {
public static void Main(string[] args) {
var mc1 = new MyClass<uint, ushort>(Workers.Method1);
var mc2 = new MyClass<ulong, uint>(Workers.Method1);
var mc3 = new MyClass<uint, ushort>(Workers.Method2);
var mc4 = new MyClass<ulong, uint>(Workers.Method2);
var mc5 = new MyClass<uint, ushort>(1);
var mc6 = new MyClass<ulong, uint>(1);
var mc7 = new MyClass<uint, ushort>(2);
var mc8 = new MyClass<ulong, uint>(2);
}
}
}
The first constructor works just fine: the compiler is able to infer the correct overload of the static worker method to pass as a parameter, which gets stored in the instance variable _doWork, and can be (reasonably) efficiently called.
The second constructor won't compile, however, The problem is the assignments to _doWork which fail because "No overload for 'Method_' matches delegate 'Func<T,U>'". I sort of get it but sort of don't. It seems the compiler knows what T and U are at compile time, is "substituting" them into the class definition when compiling, and, so, ought to be able to infer which worker method to use. Anyone know why not?
Anyway, for reasons not worth going into, I'd really like to make the second constructor work. The obvious thing to try is to "cast" Method1 or Method2 to Func<T,U>, but delegates aren't objects and can't be cast. I've found a couple of pretty ugly ways to do it (that are also horribly inefficient), but I can't help but feeling there is something easier I'm missing. Any other ideas?
EDIT: It sounds like I'm abusing generics. What I have are about 100 different combinations of possible T, U, Worker values (there's actually a fourth dimension, but ignore that), each that behave somewhat differently. I'm trying to avoid having to create a separate class for each combination. So this isn't "generics" in the sense of being able to plug in any types T and U. What, if any, alternatives are there?
Have you considered using something like a factory pattern and resolving the service in a manner similar to this example
void Main()
{
var serviceCollection = new Microsoft.Extensions.DependencyInjection.ServiceCollection();
serviceCollection.AddSingleton<IMessageDeliveryProcessor, InAppNotificationMessageProcessor>();
serviceCollection.AddSingleton<IMessageDeliveryProcessor, MessageProcessor>();
serviceCollection.AddSingleton<IMessageProcessorFactory, MessageProcessorFactory>();
var serviceProvider = serviceCollection.BuildServiceProvider();
var factoryItem = serviceProvider.GetService<IMessageProcessorFactory>();
var service = factoryItem.Resolve(DeliveryType.Email);
service.ProcessAsync("", "", "");
}
public enum DeliveryType
{
Email,
InApp,
}
public class MessageProcessorFactory : IMessageProcessorFactory
{
private readonly IServiceProvider _serviceProvider;
public MessageProcessorFactory(IServiceProvider serviceProvider) => _serviceProvider = serviceProvider;
public IMessageDeliveryProcessor? Resolve(DeliveryType deliveryType)
=> _serviceProvider
.GetServices<IMessageDeliveryProcessor>()
.SingleOrDefault(processor => processor.DeliveryType.Equals(deliveryType));
}
public interface IMessageProcessorFactory
{
IMessageDeliveryProcessor? Resolve(DeliveryType deliveryType);
}
public interface IMessageDeliveryProcessor
{
DeliveryType DeliveryType { get; }
Task ProcessAsync(string applicationId, string eventType, string messageBody);
}
public class InAppNotificationMessageProcessor : IMessageDeliveryProcessor
{
public DeliveryType DeliveryType => DeliveryType.InApp;
public Task ProcessAsync(string applicationId, string eventType, string messageBody)
{
Console.Write("InAppNotificationMessageProcessor");
return Task.CompletedTask;
}
}
public class EmailNotificationMessageProcessor : IMessageDeliveryProcessor
{
public DeliveryType DeliveryType => DeliveryType.Email;
public Task ProcessAsync(string applicationId, string eventType, string messageBody)
{
Console.Write("MessageProcessor");
return Task.CompletedTask;
}
}
This doesnt address your code and your issue exactly, but based on what I see of your issue, this could help you in the direction of travel.
In your second constructor, you are attempting to assign something not directly compatible. What you're assigning is a method group, of which nothing in the method group can match a T or a U using the compiler's type inference rules.
One thing you can do is instead of trying to assign the delegates directly in your second destructor, you can instead assign a dispatcher method that will resolve this at runtime.
Your constructor could be changed to
public MyClass(int workType)
{
if (workType == 1) _doWork = Method1Dispatcher;
else if (workType == 2) _doWork = Method2Dispatcher;
else throw new Exception();
}
where you have dispatcher methods such as
public U Method1Dispatcher(T value)
{
return value switch
{
uint x => (U)(object)Workers.Method1(x),
ulong x => (U)(object)Workers.Method1(x),
_ => throw new NotSupportedException()
};
}
public U Method2Dispatcher(T value)
{
return value switch
{
uint x => (U)(object)Workers.Method2(x),
ulong x => (U)(object)Workers.Method2(x),
_ => throw new NotSupportedException()
};
}
These methods use a double cast to get around the compile-time checks that prevent you from "equating", for instance, a uint and a T. Casting to object removes that constraint, and casts to another type, at runtime, could either succeed or fail. That's not typesafe, but if implemented carefully like the above, you at least encapsulate known (to us not the compiler) safe casts.
To test that this works, you can modify your Main method to prove it
var mc5 = new MyClass<uint, ushort>(1);
var mc5Result = mc5.DoWork(5);
Console.WriteLine($"Got result {mc5Result} of type {mc5Result.GetType().Name}");
var mc6 = new MyClass<ulong, uint>(1);
var mc6Result = mc6.DoWork(6);
Console.WriteLine($"Got result {mc6Result} of type {mc6Result.GetType().Name}");
var mc7 = new MyClass<uint, ushort>(2);
var mc7Result = mc7.DoWork(7);
Console.WriteLine($"Got result {mc7Result} of type {mc7Result.GetType().Name}");
var mc8 = new MyClass<ulong, uint>(2);
var mc8Result = mc8.DoWork(8);
Console.WriteLine($"Got result {mc6Result} of type {mc8Result.GetType().Name}");
Now, while this works, it's probably not the best solution because you say there are hundreds of combinations. Perhaps you can replace the switch with a reflection based way of obtaining the correct method, and then invoking it.
Take the following class as an example:
class Sometype
{
int someValue;
public Sometype(int someValue)
{
this.someValue = someValue;
}
}
I then want to create an instance of this type using reflection:
Type t = typeof(Sometype);
object o = Activator.CreateInstance(t);
Normally this will work, however because SomeType has not defined a parameterless constructor, the call to Activator.CreateInstance will throw an exception of type MissingMethodException with the message "No parameterless constructor defined for this object." Is there an alternative way to still create an instance of this type? It'd be kinda sucky to add parameterless constructors to all my classes.
I originally posted this answer here, but here is a reprint since this isn't the exact same question but has the same answer:
FormatterServices.GetUninitializedObject() will create an instance without calling a constructor. I found this class by using Reflector and digging through some of the core .Net serialization classes.
I tested it using the sample code below and it looks like it works great:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Runtime.Serialization;
namespace NoConstructorThingy
{
class Program
{
static void Main(string[] args)
{
MyClass myClass = (MyClass)FormatterServices.GetUninitializedObject(typeof(MyClass)); //does not call ctor
myClass.One = 1;
Console.WriteLine(myClass.One); //write "1"
Console.ReadKey();
}
}
public class MyClass
{
public MyClass()
{
Console.WriteLine("MyClass ctor called.");
}
public int One
{
get;
set;
}
}
}
Use this overload of the CreateInstance method:
public static Object CreateInstance(
Type type,
params Object[] args
)
Creates an instance of the specified
type using the constructor that best
matches the specified parameters.
See: http://msdn.microsoft.com/en-us/library/wcxyzt4d.aspx
When I benchmarked performance of (T)FormatterServices.GetUninitializedObject(typeof(T)) it was slower. At the same time compiled expressions would give you great speed improvements though they work only for types with default constructor. I took a hybrid approach:
public static class New<T>
{
public static readonly Func<T> Instance = Creator();
static Func<T> Creator()
{
Type t = typeof(T);
if (t == typeof(string))
return Expression.Lambda<Func<T>>(Expression.Constant(string.Empty)).Compile();
if (t.HasDefaultConstructor())
return Expression.Lambda<Func<T>>(Expression.New(t)).Compile();
return () => (T)FormatterServices.GetUninitializedObject(t);
}
}
public static bool HasDefaultConstructor(this Type t)
{
return t.IsValueType || t.GetConstructor(Type.EmptyTypes) != null;
}
This means the create expression is effectively cached and incurs penalty only the first time the type is loaded. Will handle value types too in an efficient manner.
Call it:
MyType me = New<MyType>.Instance();
Note that (T)FormatterServices.GetUninitializedObject(t) will fail for string. Hence special handling for string is in place to return empty string.
Good answers but unusable on the dot net compact framework. Here is a solution that will work on CF.Net...
class Test
{
int _myInt;
public Test(int myInt)
{
_myInt = myInt;
}
public override string ToString()
{
return "My int = " + _myInt.ToString();
}
}
class Program
{
static void Main(string[] args)
{
var ctor = typeof(Test).GetConstructor(new Type[] { typeof(int) });
var obj = ctor.Invoke(new object[] { 10 });
Console.WriteLine(obj);
}
}
I want to implement an extension method for a method. Consider the following code sample (http://dotnetfiddle.net/HztiOo) :
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
A a = new A();
// Noticed that Next() is called twice
Console.WriteLine(a.Next(1));
Console.WriteLine(a.Next(1));
// Works
var withCache = ((Func<int,int>)a.Next).AddCaching();
withCache = new Func<int,int>(a.Next).AddCaching();
withCache = ExtensionMethods.AddCaching<int,int>(a.Next);
// Doesn't work :(
// withCache = a.Next.AddCaching<int,int>();
// Func<int,int> withCache = a.Next.AddCaching();
// Notice that Next() is only called once
Console.WriteLine(withCache(1));
Console.WriteLine(withCache(1));
}
}
public class A
{
public int Next(int n)
{
Console.WriteLine("Called Next("+n+")");
return n + 1;
}
}
public static class ExtensionMethods
{
public static Func<TKey,TVal> AddCaching<TKey,TVal>(this Func<TKey,TVal> fetcher)
{
var cache = new Dictionary<TKey, TVal>();
return k =>
{
if (!cache.ContainsKey(k)) cache[k] = fetcher(k);
return cache[k];
};
}
}
I would like to be able to call the extension method without an explicit cast. In both "doesn't work" examples above, the type system should be able to figure out which overload to use on its own...
Why can't I just use a.Next.AddCaching<int,int>() ?
Note: this is just an example, I am not interested in discussing the best way to add a cache to a method invocation, as there are many other possibilities for this kind of extensions.
According to Eric Lippert blog method group is typeless expression. And you can't do anything, just deal with it.
That's exact reason why you can't implicitly cast it to specific delegate and add extension method to it
You can achieve something stylistically similar to what you are looking for by exposing you method as a Func, as follows (https://dotnetfiddle.net/BTyJdU). Obviously this involves modifying the class, so it can't be achieved with an extension method only.
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
A a = new A();
// Noticed that Next() is called twice
Console.WriteLine(a.Next(1));
Console.WriteLine(a.Next(1));
// Works now :)
var withCache = a.Next.AddCaching<int,int>();
withCache = a.Next.AddCaching();
// Notice that Next() is only called once
Console.WriteLine(withCache(1));
Console.WriteLine(withCache(1));
}
}
public class A
{
public Func<int,int> Next;
public A()
{
Next = NextInternal;
}
private int NextInternal(int n)
{
Console.WriteLine("Called Next("+n+")");
return n + 1;
}
}
public static class ExtensionMethods
{
public static Func<TKey,TVal> AddCaching<TKey,TVal>(this Func<TKey,TVal> fetcher)
{
var cache = new Dictionary<TKey, TVal>();
return k =>
{
if (!cache.ContainsKey(k)) cache[k] = fetcher(k);
return cache[k];
};
}
}
I've also put together a fiddle which uses extension methods only. It involves calling an extension on the object rather than the method: https://dotnetfiddle.net/XaLndp
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
A a = new A();
// Noticed that Next() is called twice
Console.WriteLine(a.Next(1));
Console.WriteLine(a.Next(1));
// An alternative, that uses extension methods only
var withCache = a.AddCaching<A,int,int>(x => x.Next);
// Notice that Next() is only called once
Console.WriteLine(withCache(1));
Console.WriteLine(withCache(1));
}
}
public class A
{
public int Next(int n)
{
Console.WriteLine("Called Next("+n+")");
return n + 1;
}
}
public static class ExtensionMethods
{
public static Func<TKey,TVal> AddCaching<T,TKey,TVal>(this T wrapped, Func<T,Func<TKey,TVal>> fetcher)
{
var cache = new Dictionary<TKey, TVal>();
return k =>
{
if (!cache.ContainsKey(k)) cache[k] = fetcher(wrapped)(k);
return cache[k];
};
}
}
You are able to write extension methods for delegates. In your example:
Why can't I just use a.Next.AddCaching() ?
In that question, a.Next isn't a type. Extension methods only work for types. Think about it. In your AddCaching extension method, what would you write after this? You need a type. In this case, you used the delegate Func<TKey,TVal>. That means it'll extend that delegate. For you example to compile, you need to write:
((Func<int,int>)a.Next).AddCaching<int,int>()
This will compile properly. Additionally, since you are defining the generic types in the delegate, you can actually call it like this:
((Func<int,int>)a.Next).AddCaching()
It'll know it is using <int,int> from the delegate.
So, you were close, you just needed to cast a.Next to a type, the delegate Func<int,int> for it to compile. It is the same rules that apply to extending any other type in the language.
I'm trying to make a generic wrapper class that can wrap any other class and add extra functionality to it. However at the same time I want to be able to use this wrapper everywhere where I would normally use the wrapped class. Currently I use implicit casting which works OK. But in an ideal world I would like to the wrapper class to have the same exposed methods and fields as the wrapped class, like in this piece of example code:
class Foo
{
public int Bar() { return 5; }
}
class Wrapper<T>
{
private T contents;
public void ExtraFunctionality() { }
public static implicit operator T(Wrapper<T> w) { return w.contents; }
}
Foo f = new Foo();
Wrapper<Foo> w = new Wrapper<Foo>(foo);
int y = w.Bar();
Can I use some ancient witchcraft, reflection, or other trickery to make this possible?
Note: in C++ I would just overload the -> operator to operate on the field contents instead of on the wrapper.
I wouldn't recommend this, but since you've mentioned witchcraft... you can use dynamic typing with DynamicObject. The wrapper tries to handle the requested method. If it can't, it forwards the call to the underlying wrapped object:
class DynamicWrapper : DynamicObject
{
private readonly object _contents;
public DynamicWrapper(object obj)
{
_contents = obj;
}
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
if (binder.Name == "ExtraFunctionality")
{
// extra functionality
return true;
}
var method = _contents.GetType()
.GetRuntimeMethods()
.FirstOrDefault(m => m.Name == binder.Name);
if (method == null)
{
result = null;
return false;
}
result = method.Invoke(_contents, args);
return true;
}
}
Edit:
Nevermind, I just noticed you wanted to use an instance of this everywhere where you would normally use an instance of the wrapped type.
You'd have to change the field/property/variable declaration to dynamic to use this.
You can generate the type(s) dynamically using the classes in the System.Reflection.Emit namespace. This link can give you a good starting point.
pologise if this questions has been asked but I couldn't find the answer anywhere.
My problem is when mocking a return method using MOQ where that method returns a dynamic type. I'm using a third part library which uses dynamic times. MOQ seems to cast the dynamic type as object.
Mock<IFacebookHelper> mockFbHelp = new Mock<IFacebookHelper>();
mockFbHelp.Setup(x => x.Get("me")).Returns(new { email = "test#test.com", id="9999" });
Method in the mocked helper.
public dynamic Get(string p)
{
var client = new FacebookClient(AccessToken);
return client.Get("me");
}
Code from controller using mocked results.
_facebookHelper.AccessToken = accessToken;
dynamic result = _facebookHelper.Get("me");
int facebookId = int.Parse(result.id); //This errors as id doesn't exist.
Basically MOQ has returned a dynamic type of object that would require casting as something.
Does anyone know how to get around this problem? I'm assuming it may be because MOQ is not coded in .NET 4 therefore does not support dynamic types?
Edit
Actually I don't think this is a MOQ issue as I created my own mock class and still had the same problem. I'm new to dynamic types though so not sure what's going on.
Edit 2 - Part answered.. Problem nothing to do with MOQ after all
Actually the problem seems to be due to the dynamic type being created in a different assembly. Although I got round my initial problem using a JObject type I still want to figure this out.
namespace MyLib.Tools
{
public interface IDynTest
{
dynamic GetData();
}
}
namespace MyLib.Tools
{
public class DynTest : Effect.Tools.IDynTest
{
public dynamic GetData() {
return new { DynamicProperty = "hello" };
}
}
}
namespace Warrior.WebUI.Infrastructure
{
public class UseDynTest
{
private readonly IDynTest dynTest;
public UseDynTest(IDynTest dynTest)
{
this.dynTest = dynTest;
}
public string RetTest()
{
return dynTest.GetData().DynamicProperty;
}
}
}
namespace Warrior.Tests
{
[TestClass]
public class TestDynTest
{
[TestMethod]
public void TestMethod1()
{
//Mock<IDynTest> mockDynTest = new Mock<IDynTest>();
//mockDynTest.Setup(x => x.GetData()).Returns(new { DynamicProperty = "From Unit Test" });
DynTestProxy dynTestProxy = new DynTestProxy();
UseDynTest useTest = new UseDynTest(dynTestProxy);
string results = useTest.RetTest();
Assert.AreEqual("From Unit Test", results);
}
}
}
namespace Warrior.Tests
{
public class DynTestProxy:IDynTest
{
public dynamic GetData()
{
return (dynamic) new { DynamicProperty = "From Unit Test" };
}
}
}
There are 3 project indicated by the Namespace MyLib, Warrior.WebUI and Warrior.Tests.
As it is the test fails with an error..
'object' does not contain a definition for 'DynamicProperty'
which occurs on RetTest()
However if I simply move the DynTestProxy class into the Warrior.WebUI project everything works fine. I'm guessing there are problems when sending dynamic types accross different assemblies or something.
I did a quick test:
namespace ConsoleApplication5
{
public interface IFacebookHelper { dynamic Get(string p); }
class Program
{
static void Main(string[] args)
{
Mock<IFacebookHelper> mockFbHelp = new Mock<IFacebookHelper>();
mockFbHelp.Setup(x => x.Get("me")).Returns(new { email = "test#test.com", id = "9999" });
dynamic result = mockFbHelp.Object.Get("me");
int facebookId = int.Parse(result.id);
string email = result.email;
}
}
}
This is working fine. I don't see a problem here.
Are you sure you didn't mix some things up?
Look at the method you posted:
public dynamic Get(string p)
{
var client = new FacebookClient(AccessToken);
return client.Get("me");
}
Maybe it should be:
...
return client.Get(p);
...
Is _facebookHelper really using the Mock object? It should be of type IFacebookHelperProxy or something like that during your test.
EDIT:
The problem is your attempt to expose an anonymous type across assembly boundaries, since you can use anonymous type only within the assembly you created them.
So instead of
public class DynTestProxy:IDynTest
{
public dynamic GetData()
{
return (dynamic) new { DynamicProperty = "From Unit Test" };
}
}
you should use an ExpandoObject:
public class DynTestProxy:IDynTest
{
public dynamic GetData()
{
dynamic r = new ExpandoObject();
r.DynamicProperty = "From Unit Test";
return r;
}
}
or use the InternalsVisibleTo attribute. See here for more information. Also this question may be interesting for you.