how to mock.SingleOrDefault() with Moq and C# - c#

I've seen a few questions like this floating around but I'm looking for a good explination of how to get around this. I understand that Moq can't mock the extension call, but I'm just looking for a really good example. In the current code I there is a call like
var thing = listOfthings.myList.SingleOrDefault(lt => lt.Name== "NameToFind");
I've tried
MockedlistOfThings.Setup(x => x.myList.SingleOrDefault(o => o.Name == "NameToFind")).Returns(fakeObject);
Just looking for a good work around. thanks.
To further elaborate on how this situation came up, we are currently running a translation engine against large sets of data, that has to be run line by line. This translation engine passes in an Interface called IListOfthings. listOfthings is actually holding reference data in a dictionary that is preloaded in another call higher up in the program. I have created a "fakeObject" <- dictionary that holds my fake data that the method can use. I have Mocked the IlistOfthings which is passed in to the calling method. but I don't see how to fake the SingleOrDefault call.
Simplifed method below.
Public class ClassIMTesting
{
public void Translate(myObject obj, IlistOfThings listOfthings){
var thing = listOfthings.MyList.SingleOrDefault(lt => lt.Name== "NameToFind");
//Other logic here .....
}
}
public class Thing()
{
public string Name { get; set; }
public Dictionary MyDict { get; set; }
}
[TestFixture()]
public class MyCodeTest
{
MyObject myObj;
Mock<IListOfthings> listOfThings;
Thing thing;
[SetUp]
public void Setup()
{
myObj = new MyObject();
_thing = new thing();
_thing.Name = "MyName";
var myDict = new Dictionary<string, string>();
myDict.Add("70,~", "");
myDict.Add("70,145", "expectedResult");
myDict.Add("911,", "expectedResult");
thing.MyDict = myDict;
listOfThings = new Mock<IListOfthings>();
listOfThings.Setup(x => x.MyList.SingleOrDefault(o => o.Name == "MyName")).Returns(thing);
}
[TestCase("70", "~", "70070")]
[TestCase("70", "145", "expectedResult")]
[TestCase("911", "", "expectedResult")]
public void TranslateTest(string iTC, string ITCode, string expectedResult)
{
myObject.ITC = iTC;
myObject.ITCode = iTCode;
ClassIMTesting p = new ClassIMTesting();
p.Translate(myObject, listofThings.Object);
Assert.That(myObject.ITC3Code, Is.EqualTo(expectedResult));
}
}
public interface IListOfThings
{
List<Thing> MyList{ get; set; }
}

Given
public interface IListOfThings {
List<Thing> MyList { get; set; }
}
public class Thing() {
public string Name { get; set; }
public Dictionary MyDict { get; set; }
}
In order to provide a mock to satisfy the following example
public class ClassImTesting {
public Thing Translate(IlistOfThings listOfthings){
var thing = listOfthings.MyList.SingleOrDefault(lt => lt.Name== "NameToFind");
return thing
}
}
The mock just needs to return a collection that will allow the SingleOrDefault extension to behave as expected when invoked.
For example
//Arrrange
Mock<IListOfthings> listOfThings = new Mock<IListOfthings>();
var thing = new Thing {
Name = "NameToFind",
//...
};
List<Thing> list = new List<Thing>() { thing };
listOfThings.Setup(_ => _.MyList).Returns(list);
var subject = new ClassImTesting();
//Act
var actual = subject.Translate(listOfThings.Object);
//Assert
Assert.That(actual, Is.EqualTo(thing));
By having the mock return an actual List<Thing>, when
var thing = listOfthings.MyList.SingleOrDefault(lt => lt.Name== "NameToFind");
is invoked, the SingleOrDefault extension acts on a list where I can behave as expected.

Related

Unit testing and mocking domain objects

I have a domain class, which looks like this:
public class Employee
{
public Guid EmployeeId { get; private set; }
public string Name { get; private set; }
public string Surname { get; private set; }
...
// other properties
public ICollection<Language> Languages { get; private set; }
= new List<Language>();
public ICollection<Skill> Skills { get; private set; }
= new List<Skill>();
public void AddLanguage(Language language)
{
if (language == null)
return;
Languages.Add(language);
}
public void DeleteLanguage(Guid languageId)
{
var languageToDelete = Languages
.SingleOrDefault(x => x.LanguageId == languageId);
if(languageToDelete == null)
throw new ArgumentException("Language entry doesn't exist.");
Languages.Remove(languageToDelete);
}
}
I would like to test given methods but I'm stuck.
I have:
[Fact]
public void AddLanguage_AfterCallWithValidObject_LanguagesCollectionContainsAddedObject()
{
var language = new Mock<Language>();
var employee = new Employee("Name", "Surname", ...);
employee.AddLanguage(language.Object);
Assert.Contains(employee.EmployeeLanguages, x => x.Language.Equals(language.Object));
}
[Fact]
public void DeleteLanguage_WhenLanguageWithGivenIdDoesntExist_ThrowArgumentException()
{
var languageToDelete = new Language("English");
var employee = new Mock<Employee>();
employee.Setup(x => x.Languages).Returns(new List<Languages>
{
new Language("Spanish"),
new Language("German")
});
employee.Object.DeleteLanguage(languageToDelete);
// Asserts here
}
In the first test I would like also assert that Languages.Add(skill) method was called but I have no idea how to do it.
Is it an elegant way to do it? I thought about mocking Add method but I'm not sure if it is a good idea.
In the second test I cannot simply mock Employee object as it is not an interface.
I thought about exposing Employee but I read I should not do that just for testing purpose.
How should I mock Languages property without exposing Employee as interface? Is it possible? Is it any good practice to do this kind of things?
Is my general concept for test these methods is okay? (I'm new in unit testing)
You should tests objects as "black box" without relying on implementation details. In your case implementation details is that Employee class uses ICollection.Add method.
And you definitely don't need to mock at all in your case.
Mock only dependencies which will make tests slow or very very very very complex to configure for the test.
[Fact]
public void AddLanguage_ShouldSaveGivenLanguage()
{
var language = new Language();
var employee = new Employee("Name", "Surname");
employee.AddLanguage(language);
var expectedLanguages = new[] { language };
employee.EmployeeLanguages.Should().BeEquivalentTo(expectedLanguages);
}
Use public API Employee class provide to setup it for the test (back box).
For testing DeleteLanguage add dummy languages through public API of the class.
[Fact]
public void DeleteLanguage_WhenLanguageExists_Remove()
{
var language1 = new Language("German");
var language2 = new Language("French");
var languageToDelete = new Language("English");
var employee = new Employee("Name", "Surname");
employee.AddLanguage(language1);
employee.AddLanguage(language2);
employee.AddLanguage(languageToDelete);
employee.DeleteLanguage(languageToDelete);
var expectedLanguages = new[] { language1, language2 };
employee.EmployeeLanguages.Should().BeEquivalentTo(expectedLanguages);
}
[Fact]
public void DeleteLanguage_WhenLanguageNotExists_ThrowException()
{
var language1 = new Language("German");
var language2 = new Language("French");
var notExistedLanguage = new Language("English");
var employee = new Employee("Name", "Surname");
employee.AddLanguage(language1);
employee.AddLanguage(language2);
Action delete = () => employee.DeleteLanguage(languageToDelete);
delete.Should()
.Throw<ArgumentException>()
.WithMessage("Language entry doesn't exist.");
}
Did you notice how cumbersome employee.EmployeeLanguages reads, you can rename property to just employee.Languages.
For readable assertions I used FluentAssertions library
For domain objects with very simple behavior and no dependencies, mocking isn't strictly needed. You can test Add simply with this:
//Arrange
var e = new Employee();
var l = new Mock<Language>();
//Act
e.AddLanguage(l.Object);
//Assert
Assert.IsTrue(e.Languages.Contains(l.Object));
Testing in this fashion you can achieve perfectly good code coverage and plenty of confidence that the Employee class works as designed.

How to mock nested properties and objects and their functions?

I have the code below which I would like to test, but I'm not sure whether it is possible or not.
I have EF repositories and they are put together to a class as public properties. I don't know exactly whether it is bad solution or not, but it is easier to manage the code and its dependencies. Only the testability is still a question.
Purpose of my test is injecting data via
administrationRepository.ModuleScreen.GetAll()
method and catch the result. I know that it can be tested once it is deployed, but I want the tests in build time in order to have as fast feedback as possible.
I went through questions and answers here, but I cannot find answers. In my code I got to the point where the property is set up, but when I call the administrationRepoMock.Object.ModuleScreen.GetAll() ReSharper offers only the methods coming from Entitiy Framework and not the Moq related functions.
It is possible what I want? If so, how? Is my design suitable for this? If not can you give me articles, urls where I can see examples?
Repository:
public interface IModuleScreen
{
IEnumerable<DomainModel.Administration.ModuleScreen> GetAll();
}
public interface IAdministrationRepository
{
IModuleScreen ModuleScreen { get; }
}
public partial class AdministrationRepository : IAdministrationRepository
{
public virtual IModuleScreen ModuleScreen { get; private set; }
public AdministrationRepository( IModuleScreen moduleScreen )
{
this.ModuleScreen = moduleScreen;
}
}
Application:
public partial class DigitalLibraryApplication : IDigitalLibraryApplication
{
private IAdministrationRepository _administrationRepository;
private IMapper.IMapper.IMapper _mapper;
private IDiLibApplicationHelper _dilibApplicationHelper;
#region Ctor
public DigitalLibraryApplication( IAdministrationRepository administrationRepository, IMapper.IMapper.IMapper mapper, IDiLibApplicationHelper diLibApplicationHelper)
{
_administrationRepository = administrationRepository;
_mapper = mapper;
_dilibApplicationHelper = diLibApplicationHelper;
}
#endregion
public IEnumerable<ModuleScreenContract> GetModuleScreens()
{
//inject data here
IEnumerable<ModuleScreen> result = _administrationRepository.ModuleScreen.GetAll();
List<ModuleScreenContract> mappedResult = _mapper.MapModuleScreenToModuleScreenContracts(result);
return mappedResult;
}
}
Test code:
[Test]
public void ItCalls_ModuleRepository_Get_Method()
{
List<SayusiAndo.DiLib.DomainModel.Administration.ModuleScreen> queryResult = new List<SayusiAndo.DiLib.DomainModel.Administration.ModuleScreen>()
{
new DomainModel.Administration.ModuleScreen()
{
Id = 100,
},
};
var moduleScreenMock = new Mock<IModuleScreen>();
moduleScreenMock.Setup(c => c.GetAll()).Returns(queryResult);
administrationRepoMock.SetupProperty(c => c.ModuleScreen, moduleScreenMock.Object);
var mapperMock = new Mock<IMapper.IMapper.IMapper>();
var dilibApplicationHerlperMock = new Mock<IDiLibApplicationHelper>();
IDigitalLibraryApplication app = new DigitalLibraryApplication( administrationRepoMock.Object, mapperMock.Object, dilibApplicationHerlperMock.Object );
app.GetModules();
//issue is here
administrationRepoMock.Object.ModuleScreen.GetAll() //???
}
Here is a refactoring of your test that passes when run. You can update the pass criteria to suit you definition of a successful test.
[Test]
public void ItCalls_ModuleRepository_Get_Method() {
// Arrange
List<ModuleScreen> queryResult = new List<ModuleScreen>()
{
new ModuleScreen()
{
Id = 100,
},
};
//Building mapped result from query to compare results later
List<ModuleScreenContract> expectedMappedResult = queryResult
.Select(m => new ModuleScreenContract { Id = m.Id })
.ToList();
var moduleScreenMock = new Mock<IModuleScreen>();
moduleScreenMock
.Setup(c => c.GetAll())
.Returns(queryResult)
.Verifiable();
var administrationRepoMock = new Mock<IAdministrationRepository>();
administrationRepoMock
.Setup(c => c.ModuleScreen)
.Returns(moduleScreenMock.Object)
.Verifiable();
var mapperMock = new Mock<IMapper>();
mapperMock.Setup(c => c.MapModuleScreenToModuleScreenContracts(queryResult))
.Returns(expectedMappedResult)
.Verifiable();
//NOTE: Not seeing this guy doing anything. What's its purpose
var dilibApplicationHerlperMock = new Mock<IDiLibApplicationHelper>();
IDigitalLibraryApplication app = new DigitalLibraryApplication(administrationRepoMock.Object, mapperMock.Object, dilibApplicationHerlperMock.Object);
//Act (Call the method under test)
var actualMappedResult = app.GetModuleScreens();
//Assert
//Verify that configured methods were actually called. If not, test will fail.
moduleScreenMock.Verify();
mapperMock.Verify();
administrationRepoMock.Verify();
//there should actually be a result.
Assert.IsNotNull(actualMappedResult);
//with items
CollectionAssert.AllItemsAreNotNull(actualMappedResult.ToList());
//There lengths should be equal
Assert.AreEqual(queryResult.Count, actualMappedResult.Count());
//And there should be a mapped object with the same id (Assumption)
var expected = queryResult.First().Id;
var actual = actualMappedResult.First().Id;
Assert.AreEqual(expected, actual);
}

Setup for testing a Linq query on a LinqToExcel IExcelQueryFactory

Using c#, Moq, MSTest, LinqToExcel
I'm having trouble figuring out the best way to Setup() a mock for a response from a Linq query on a Linq-to-Excel IExcelQueryFactory.
I think I should expect the Linq Query to return something of type delegate, but I'm not quite sure what that should look like
Can anyone suggest what my Return() should look like in the Moq Setup() below?
Also, any toughts on my approach to testing and mocking these Lynq methods? Should I be approaching this differently?
Thanks! I'm going to go book up on delegates now. :)
The Test
[TestClass]
public class ThingsSheetTests
{
[TestMethod]
public void GetRows_ReturnsListOfThings()
{
// Arrange
var mockExcelQueryFactory = new Mock<IExcelQueryFactory>();
var thingsSheet = new ThingsSheet(mockExcelQueryFactory.Object, "file", "worksheet");
mockExcelQueryFactory
.Setup(x => x.Worksheet<Thing>(It.IsAny<string>))
// I think this is correctly casting to a delegate
// however ExelQuerable constructor needs arguments:
// public ExcelQueryable(IQueryProvider provider, Expression expression);
// looking into what kind of IQueryProvider and Expression I should supply.
.Returns(Action(() => new ExcelQueryable<Thing> { })); // getting closer!
// Act
thingsSheet.GetRows();
// Assert
mockExcelQueryFactory.Verify();
}
}
The Class and Method I'm testing
public class ThingsSheet
{
private string importFile;
private string worksheetName;
private IExcelQueryFactory excelQueryFactory;
public ThingsSheet(IExcelQueryFactory excelQueryFactory, string importFile, string worksheetName)
{
this.excelQueryFactory = excelQueryFactory;
this.importFile = importFile;
this.worksheetName = worksheetName;
this.AddMappings();
}
private void AddMappings()
{
excelQueryFactory.AddMapping<Thing>(t => t.Id, "Thing ID");
}
public List<Thing> GetRows()
{
excelQueryFactory.AddMapping<Thing>(t => t.Id, "Thing ID");
var things = from thing in excelQueryFactory.Worksheet<Thing>(this.worksheetName)
select new Thing { };
return things.ToList<Thing>();
}
}
You can use e.g. a method which returns your fake data.
mockExcelQueryFactory
.Setup(x => x.Worksheet<Thing>(It.IsAny<string>()))
.Returns(ExcelQueryableOfThing());
Lets say Thing class looks like this:
public class Thing
{
public string Id { get; set; }
public string Name { get; set; }
}
Then in the method ExcelQueryableOfThing() you have to mock the CreateQuery<TElement>(Expression expression) method of IQueryProvider provider. Something like this:
private ExcelQueryable<Thing> ExcelQueryableOfThing()
{
var things = new List<Thing>
{
new Thing
{
Id = "1",
Name = "Adam"
},
new Thing
{
Id = "1",
Name = "Eva"
}
}
.AsQueryable();
Mock<IQueryProvider> queryProvider = new Mock<IQueryProvider>();
queryProvider
.Setup(p => p.CreateQuery<Thing>(It.IsAny<Expression>()))
.Returns(() => things);
Expression expressionFake = Expression.Constant(new List<Thing>().AsQueryable());
return new ExcelQueryable<Thing>(queryProvider.Object, expressionFake);
}
Then in the unit test thingsSheet.GetRows() will return your fake data (Adam and Eva :). HTH
[TestMethod]
public void GetRows_ReturnsListOfThings()
{
// Arrange
Mock<IExcelQueryFactory> mockExcelFile = new Mock<IExcelQueryFactory>();
var thingsSheet = new ThingsSheet(mockExcelFile.Object, "file", "worksheet");
mockExcelFile
.Setup(x => x.Worksheet<Thing>(It.IsAny<string>()))
.Returns(ExcelQueryableOfThing());
// Act
List<Thing> rows = thingsSheet.GetRows();
// Assert
Assert.AreEqual(2, rows.Count); // Adam and Eva
}

Mocking with moq, trying to pass an object to constructor having multiple parameter

I am trying to mock a method that returns a IEnumerable set of data, like a list of all codes.
There is an Interface ISystemService.cs that contains this method, a service class called SystemService.cs that has the method definition.
System under test is:
public static class CacheKeys
{
public const string ALLCURRENCYCODES = "CurrencyCodes";
}
public interface ICacheManager
{
T Get<T>(string key);
void Set(string key, object data, int cacheTime);
void Clear();
}
public interface ISessionManager
{
}
public interface IApplicationSettings
{
string LoggerName { get; }
int CacheTimeout { get; }
}
public class EFDbContext : DbContext
{
public DbSet<CurrencyCode> CurrencyCodes { get; set; }
}
public class CurrencyCode
{
public string Code { get; set; }
public string Description { get; set; }
public decimal CurrencyUnit { get; set; }
public int? DecimalPlace { get; set; }
public string BaseCurrencyCode { get; set; }
}
public interface ISystemService
{
IEnumerable<CurrencyCode> GetAllCurrencyCodes();
}
//SystemService.cs
public class SystemService : ISystemService
{
private readonly EFDbContext db;
private readonly ICacheManager cacheManager;
private readonly ISessionManager sessionManager;
private readonly IApplicationSettings appSettings;
public SystemService(EFDbContext dbContext, ICacheManager cacheManager, ISessionManager sessionManager, IApplicationSettings appSettings)
{
db = dbContext;
this.cacheManager = cacheManager;
this.sessionManager = sessionManager;
this.appSettings = appSettings;
}
public IEnumerable<CurrencyCode> GetAllCurrencyCodes()
{
var allCurrencyCodes = cacheManager.Get<IEnumerable<CurrencyCode>>(CacheKeys.ALLCURRENCYCODES);
if (allCurrencyCodes == null)
{
allCurrencyCodes = db.CurrencyCodes.ToList();
cacheManager.Set(CacheKeys.ALLCURRENCYCODES, allCurrencyCodes, appSettings.CacheTimeout);
}
return allCurrencyCodes;
}
Test Method
[TestMethod]
public void testCacheMiss()
{
List<CurrencyCode> currencycodes = new List<CurrencyCode>()
{
new CurrencyCode(){Id = 1, Code = "IND", Description = "India"},
new CurrencyCode(){Id = 2, Code = "USA", Description = "UnitedStates"},
new CurrencyCodes(){Id = 3, Code = "UAE", Description = "ArabEmirates"}
};
var mockEfContext = new Mock<EFDbContext>();
var mockCacheManager = new Mock<ICacheManager>();
var mockSessionManager = new Mock<ISessionManager>();
var mockAppSettings = new Mock<IApplicationSettings>();
// Setups for relevant methods of the above here, e.g. to test a cache miss
mockEfContext.SetupGet(x => x.CurrencyCodes)
.Returns(currencycodes); // Canned currencies
mockCacheManager.Setup(x => x.Get<IEnumerable<CurrencyCode>>(It.IsAny<string>()))
.Returns<IEnumerable<CurrencyCodes>>(null); // Cache miss
// Act
var service = new SystemService(mockEfContext.Object, mockCacheManager.Object,
mockSessionManager.Object, mockAppSettings.Object);
var codes = service.GetAllCodes();
// Assert + Verify
mockCacheManager.Verify(x => x.Get<IEnumerable<CurrencyCodes>>(
It.IsAny<string>()), Times.Once, "Must always check cache first");
mockEfContext.VerifyGet(x => x.CurrencyCodes,
Times.Once, "Because of the simulated cache miss, must go to the Db");
Assert.AreEqual(currencycodes.Count, codes.Count(), "Must return the codes as-is");
Since the defined constructor does not accept one parameter, how to pass the object as parameter? Please advice
If CodeService is under test, then you want to be mocking its dependencies, not the CodeService itself.
You'll need to provide Mocks for all of the dependencies of CodeService to the constructor, i.e.:
var currencycodes = new List<SomeCodes>
{
new CurrencyCodes(){Id = 1, Code = "IND", Description = "India"},
new CurrencyCodes(){Id = 2, Code = "USA", Description = "UnitedStates"},
new CurrencyCodes(){Id = 3, Code = "UAE", Description = "ArabEmirates"}
};
var mockEfContext = new Mock<EFDbContext>();
var mockCacheManager = new Mock<ICacheManager>();
var mockSessionManager = new Mock<ISessionManager>();
var mockAppSettings = new Mock<IApplicationSettings>();
// Setups for relevant methods of the above here, e.g. to test a cache miss
mockEfContext.SetupGet(x => x.SomeCodes)
.Returns(currencycodes); // Canned currencies
mockCacheManager.Setup(x => x.Get<IEnumerable<SomeCodes>>(It.IsAny<string>()))
.Returns<IEnumerable<SomeCodes>>(null); // Cache miss
// Act
var service = new CodeService(mockEfContext.Object, mockCacheManager.Object,
mockSessionManager.Object, mockAppSettings.Object);
var codes = service.GetAllCodes();
// Assert + Verify
mockCacheManager.Verify(x => x.Get<IEnumerable<SomeCodes>>(
It.IsAny<string>()), Times.Once, "Must always check cache first");
mockEfContext.VerifyGet(x => x.SomeCodes,
Times.Once, "Because of the simulated cache miss, must go to the Db");
Assert.AreEqual(currencycodes.Count, codes.Count(), "Must return the codes as-is");
Edit If you however mean that the next layer up of your code is under test, the principal is the same:
var mockCodeService = new Mock<ICodeService>();
mockCodeService.Setup(x => x.GetAllCodes())
.Returns(currencycodes); // Now we don't care whether this is from cache or db
var higherLevelClassUsingCodeService = new SomeClass(mockCodeService.Object);
higherLevelClassUsingCodeService.DoSomething();
mockCodeService.Verify(x => x.GetAllCodes(), Times.Once); // etc
Edit 2
I've fixed a couple of typos in the code, and assuming CurrencyCodes inherits SomeCodes and that your cache key is a string, and pushed it up onto a Git Gist here with the corresponding cache miss unit test as well. (I've used NUnit, but it isn't really relevant here)
allCodes is your service.. its the mock you need to be working with. You shouldn't be creating a concrete instance of your ICodeService.. your mock exists to fill that role.
So, remove this:
var service = new CodeService(allCodes.object);
Your next line should be:
var code = allCodes.Object.GetAllCodes();
But then.. this test seems completely redundant after that.. since you appear to be testing your mock..
Also, allCodes should be called serviceMock.. as that makes more sense.

Custom generic DTO Assembler

I'm trying to create a method which can be used like this:
Assembler.CreateTransfer(i);
i is an item inside a dynamic collection.
i is a domain object.
CreateTransfer() should return an instance of i type + Transfer (if my domain object is User, then it should return an instance of UserTransfer.
As for my models is like this:
public abstract class UserBase {
public long UserId { get; set; }
public string Username { get; set; }
}
public class UserTransfer : UserBase, ITransferObject { }
public partial class User : UserTransfer, IModelBase, IDomainObject {
public User() {
Roles = new List<Role>();
}
public virtual ICollection<Role> Roles { get; set; }
}
So far, I've accomplished this:
public static TTransfer CreateTransfer<TTransfer, TDomain>(TDomain d)
where TTransfer : ITransferObject
where TDomain : IDomainObject
{ ... }
This works, because I know the type of TTransfer and TDomain.
And I can call it like: CreateTransfer<UserTransfer, User>(d).
The problem comes when I try create the dto without specifying any type:
CreateTransfer(d);
Of course I've added an overload for this task and I hope I can magically accomplish the following:
public static ITransferObject CreateTransfer(IDomainObject d) {
// do magic
return CreateTransfer<transfer, domain>(d);
}
But in the real world, this is as far as I could get:
public static ITransferObject CreateTransfer(IDomainObject d) {
var dType = d.GetType();
var assemblyName = dType.Assembly.FullName;
var domainName = dType.FullName;
var transferName = domainName + "Transfer";
var domain = Activator.CreateInstance(assemblyName, domainName).UnWrap();
var transfer = Activator.CreateInstance(assemblyName, transferName).UnWrap();
return CreateTransfer< ?, ?>(d); // Problem
}
Both domain and transfer objects are being created correctly.
The main question is: Is there any way to be able to call CreateTransfer<domain, transfer>(d)? Any help will be appreciated.
You can use reflection to call the generic method.
Something like this:
var method = typeof(ClassThatDefinesCreateTransfer)
.GetMethods()
.Single(x => x.Name == "CreateTransfer" &&
x.IsGenericMethodDefinition)
.MakeGenericMethod(dType, transferType);
return (ITransferObject )method.Invoke(null, new object[] { d });
You probably want to cache at least the result of typeof(ClassThatDefinesCreateTransfer).GetMethods().

Categories