I'm trying to learn AutoFixture, and I've got xUnit and NSubstitute and AutoFixture setup to automatically mock out properties with fakes (with AutoFixture.AutoNSubstitute). In other words, if I have the following interface
public interface IFoo
{
IBar1 Bar1 {get;}
IBar2 Bar2 {get; set;}
}
Trying to resolve an IFoo will automatically resolve and populate Bar1 and Bar2.
Everything works great for objects with properties of interface, concrete object, or structure types. I'm having a problem getting AutoFixture to automatically create properties of abstract types however.
I have tried using a TypeRelay for the abstract type, so
fixture.Customizations.Add(new TypeRelay(typeof (AbstractBase), typeof (ConcreteChild)));
I have tried specifying it this way,
fixture.Customize<AbstractBase>(
composer =>
composer.FromFactory(
(string ChildParam1, string ChildParam2) => new ConcreteChild(ConcreteChildParam1, ConcreteChildParam2)));
I have tried using various custom specimen builders
Resolving via the property type:
var pi = request as PropertyInfo;
if (pi != null &&
pi.PropertyType == typeof(AbstractBase))
return context.Resolve(typeof(ConcreteChild));
return new NoSpecimen(request);
Resolving via the class type:
var pi = request as Type;
if (pi != null &&
pi == typeof (AbstractBase))
return context.Resolve(typeof(ConcreteChild));
return new NoSpecimen(request);
With both of the above solutions, I also tried context.Create<ConcreteChild>()
Finally I have tried using the Register<AbstractBase>(fixture.Create<ConcreteChild>); syntax.
None of them seem to work as far as automatically populating properties on an object.
The irritating thing is that I can explicitly fixture.Create<AbstractBase>(); in an individual test and get the ConcreteChild and then hand-jam everything but that kind of defeats the purpose of AutoFixture no?
Any ideas?
UPDATE:
The abstract class. I've pruned most of the irrelivent stuff, left the ctor code in as I'm assuming it gets called?
public abstract class ChatEntityId
{
private string _localName;
protected ChatEntityId(string chatRoomName, string entityUid, ChatProtocol protocol)
{
ErrorChecker.NormalizeToNullIfNotSet(ref chatRoomName);
ErrorChecker.NormalizeToNullIfNotSet(ref entityUid);
if (chatRoomName == null && entityUid == null)
{
throw new ArgumentException("Both chatRoomName and entityUid may not be null at the same time.");
}
ChatRoomName = chatRoomName;
EntityUid = entityUid;
Protocol = protocol;
}
public string ChatRoomName { get; private set; }
public string EntityUid { get; private set; }
public bool Equals(ChatEntityId chatEntityId) { }
public override bool Equals(object obj) { }
public override int GetHashCode() {}
public string LocalName { get; }
public ChatProtocol Protocol { get; private set; }
public override string ToString() { }
}
ChatProtocol is an enum, fairly standard.
The AutoPopulatedProperty ICustomization
public virtual void Customize(IFixture fixture)
{
fixture.Customize(new DomainCustomization());
// Replacement for the AutoNSubstituteCustomization, this Postprocessor will automatically create fake objects on properties.
fixture.ResidueCollectors.Add(
new Postprocessor(
new NSubstituteBuilder(
new MethodInvoker(
new NSubstituteMethodQuery())),
new AutoPropertiesCommand(
new PropertiesOnlySpecification())));
}
private class PropertiesOnlySpecification : IRequestSpecification
{
public bool IsSatisfiedBy(object request)
{
return request is PropertyInfo;
}
}
Somewhat embarrassingly, I realized that NSubstitute has what it calls recursive mocking, which is partially what I want and explains why I couldn't figure out where some of the auto-mocked properties were coming from. The problem is that it doesn't do it across the board (probably rightfully so), and isn't really extensible in that regard as far as I can tell.
Now AutoFixture comes into play, after we create the specimen in the Postprocessors NSubstituteBuilder, the AutoPropertiesCommand class is called and fetches what it determines are the appropriate properties to populate with data.
Unfortunately none of the logic in the two relevant classes (there is a non-generic inheriting from a generic AutoPropertiesCommand class) is overridable and this is where the problem occurs. Specifically, AutoPropertiesCommand<T> has two methods it uses to get properties and fields, which it then filters using the supplied IRequestSpecification (PropertiesOnlySpecification in this case).
The method in question
private IEnumerable<PropertyInfo> GetProperties(object specimen)
{
return from pi in this.GetSpecimenType(specimen).GetProperties(BindingFlags.Public | BindingFlags.Instance)
where pi.GetSetMethod() != null
&& pi.GetIndexParameters().Length == 0
&& this.specification.IsSatisfiedBy(pi)
select pi;
}
So the solution here is to either provide my own AutoPropertiesCommand implementation without the above limitations or explicitly create customizations for each case I run across. Haven't decided which approach I like better but probably the former.
As a side-bar it seems kind of restrictive to not have those two methods as protected virtual, is there any particular reason for this beyond "it was just coded that way"? Those are base AutoFixture classes I believe, for the record.
Related
Background:
I am working with an organization that has an ever-growing collection of data types that they need to extract data from. I have no ability to change these data types. Some are machine-generated from XML files provided by other organizations; some are controlled by intransigent internal dev teams; and some are so old that no one is willing to change them in any way for fear that it will destabilize the entire Earth and cause it to crash into the sun. These classes don't share any common interface, and don't derive from any common type other than object. A few sample classes are given below for illustration purposes:
public class Untouchable
{
public string Data;
}
public class Unchangeable
{
public int Info;
}
The good news is that most of the time, I can use canned functionality to get at least some of the data from instances of the various classes. Unfortunately, most of these classes also have weird and specialized data that needs class-specific logic to extract data from. Also, information often needs to persist inside of the data extractors because the data objects I'm pulling data from have "interactions" (don't ask).
I have created an abstract generic Extractor<T> class to serve as a repository of common methodology, and an IExtractor<T> interface to serve as a convenient handle to access functionality. I also have a few specific (de-generic?) implementations of this class that can extract information from the business objects built from some of the data types. Here's some sample code to illustrate:
public interface IExtractor<T>
{
string ExtractionOne(T something);
string ExtractionTwo(T something);
}
public abstract class Extractor<T> : IExtractor<T>
{
private string internalInfo; // Certain business logic requires us to keep internal info over multiple objects that we extract data from.
protected Extractor() { internalInfo="stuff"; }
public virtual string ExtractionOne(T something)
{
return "This manipulation is generally applicable to most conceivable types.";
}
public abstract string ExtractionTwo(T something); // This DEFINITELY needs to be overridden for each class T
}
public class UntouchableExtractor : Extractor<Untouchable>
{
public UntouchableExtractor() : base() { }
public override string ExtractionTwo(Untouchable something)
{
return something.Data;
}
}
public class UnchangeableExtractor : Extractor<Unchangeable>
{
public UnchangeableExtractor() : base() { }
public override string ExtractionTwo(Unchangeable something)
{
return something.Info.ToString();
}
}
I don't yet support all of the available data types, but management wants to roll out the data extractor to end-users using a command-line interface. They're telling me that we should start extracting the data we can extract, and get to the rest later. Support for the many unmodifiable types will be added by me and by and other programmers as time permits, and the end-users are expected to work around our latency. This actually makes sense in our real-world setting, so just go with it.
The Problem:
The list of data types that we want to pull information from is very large. Maintaining an explicit list of supported types in code will be tricky and error prone -- especially if we find any problems with specific data extractors and need to revoke support until we fix some bugs.
I would like to support the large and changing list of supported data types from a single entry point that dynamically determines the "right version" of IExtractor<> to use based on a passed in dynamic dataObject. If there is no class that implements the IExtractor<> to support the given dataObject, than an error should be thrown.
What Doesn't Work:
I tried taking a dynamic thing and using typeof(Extractor<>).MakeGenericType(thing.GetType()) to create an instance of Extractor<Untouchable> or Extractor<Unchangeable>, but those are abstract classes, so I can't use Activator.CreateInstance() to build an instance of those classes. The core issue with this approach is that it's unfortunately looking for a class of the form Extractor<> instead of an interface of the form IExtractor<>.
I considered putting extension methods like IExtractor<T> BuildExtractor(this T something) in some class, but I'm nervous about running into some business logic called BuildExtractor that already exists in one of these untouchable classes. This may be an unhealthy level of paranoia, but that's where I'm at.
Where I need help:
I'd welcome any suggestions for how I can create a single entrypoint for an unconstrained collection of classes. Thanks in advance.
Combining some code from StackOverflow and my own testing, I suggest using Reflection to find all types implementing an interface:
public static class TypeExt {
public static bool IsBuiltin(this Type aType) => new[] { "/dotnet/shared/microsoft", "/windows/microsoft.net" }.Any(p => aType.Assembly.CodeBase.ToLowerInvariant().Contains(p));
public static IEnumerable<Type> ImplementingTypes(this Type interfaceType, bool includeAbstractClasses = false, bool includeStructs = false, bool includeSystemTypes = false, bool includeInterfaces = false) =>
AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(a => a.GetLoadableTypes())
.Distinct()
.Where(aType => (includeAbstractClasses || !aType.IsAbstract) &&
(includeInterfaces ? aType != interfaceType : !aType.IsInterface) &&
(includeStructs || !aType.IsValueType) &&
(includeSystemTypes || !aType.IsBuiltin()) &&
interfaceType.IsAssignableFrom(aType) &&
aType.GetInterfaces().Contains(interfaceType));
}
public static class AssemblyExt {
//https://stackoverflow.com/a/29379834/2557128
public static IEnumerable<Type> GetLoadableTypes(this Assembly assembly) {
if (assembly == null)
throw new ArgumentNullException("assembly");
try {
return assembly.GetTypes();
} catch (ReflectionTypeLoadException e) {
return e.Types.Where(t => t != null);
}
}
}
Reflection can be quite slow, and in my testing, getting all loaded types was the slowest part, so I added caching of the loaded types and the implementing types, but this does mean you will need to refresh the loaded types if you dynamically load assemblies:
public static class TypeExt {
public static bool IsBuiltin(this Type aType) => new[] { "/dotnet/shared/microsoft", "/windows/microsoft.net" }.Any(p => aType.Assembly.CodeBase.ToLowerInvariant().Contains(p));
static Dictionary<Type, HashSet<Type>> FoundTypes = null;
static List<Type> LoadableTypes = null;
public static void RefreshLoadableTypes() {
LoadableTypes = AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetLoadableTypes()).ToList();
FoundTypes = new Dictionary<Type, HashSet<Type>>();
}
public static IEnumerable<Type> ImplementingTypes(this Type interfaceType, bool includeAbstractClasses = false, bool includeStructs = false, bool includeSystemTypes = false, bool includeInterfaces = false) {
if (FoundTypes != null && FoundTypes.TryGetValue(interfaceType, out var ft))
return ft;
else {
if (LoadableTypes == null)
RefreshLoadableTypes();
var ans = LoadableTypes
.Where(aType => (includeAbstractClasses || !aType.IsAbstract) &&
(includeInterfaces ? aType != interfaceType : !aType.IsInterface) &&
(includeStructs || !aType.IsValueType) &&
(includeSystemTypes || !aType.IsBuiltin()) &&
interfaceType.IsAssignableFrom(aType) &&
aType.GetInterfaces().Contains(interfaceType))
.ToHashSet();
FoundTypes[interfaceType] = ans;
return ans;
}
}
}
public static class AssemblyExt {
//https://stackoverflow.com/a/29379834/2557128
public static IEnumerable<Type> GetLoadableTypes(this Assembly assembly) {
if (assembly == null)
throw new ArgumentNullException("assembly");
try {
return assembly.GetTypes();
}
catch (ReflectionTypeLoadException e) {
return e.Types.Where(t => t != null);
}
}
}
Once you have one of these, you can make a factory method that takes a dynamic object:
public static class ImplementingFactory {
public static Type ExtractorType(dynamic anObject) {
Type oType = anObject.GetType();
var iType = typeof(IExtractor<>).MakeGenericType(oType);
var ans = iType.ImplementingTypes().FirstOrDefault();
if (ans == null)
throw new Exception($"Unable to find IExtractor<{oType.Name}>");
else
return ans;
}
}
The following snippet will create the concrete instance of Extractor<T> class and dynamically invokes a method of this instance
var test = new Unchangeable();
var baseType = typeof(Extractor<>).MakeGenericType(test.GetType());
var extractorType = Assembly.GetExecutingAssembly()
.GetTypes().FirstOrDefault(t => t.IsClass && !t.IsAbstract && t.IsSubclassOf(baseType));
if (extractorType != null)
{
dynamic extractor = Activator.CreateInstance(extractorType);
string result = extractor?.ExtractionTwo(test);
}
Of course, it's simplified, you can pass a specific instance of Unchangeable or Untouchable class and restrict assembly types scanning (and get all types only once).
The disadvantage here is that you have to pay attention to ExtractionOne and ExtractionTwo signatures, since they are invoked on dynamic object
The core issue with this approach is that it's unfortunately looking
for a class of the form Extractor<> instead of an interface of the
form IExtractor<>.
This snippet can help you to look through types using IExtrator<> interface
var baseType = typeof(IExtractor<>).MakeGenericType(typeof(Unchangeable));
var extractorType = Assembly.GetExecutingAssembly()
.GetTypes().FirstOrDefault(t => t.IsClass && !t.IsAbstract && baseType.IsAssignableFrom(t));
I am working on a WCF service and I have run into a bit of a snag mapping my entities to my DTO. Consider the following
namespace Foo.Entities
{
public class Order : IOrder
{
public string Name { get;set; }
public string Address { get;set; }
public IList<ILocation> Locations { get;set; }
}
}
namespace Foo.DTO
{
[DataContract]
public class Order
{
[DataMember]
public string Name { get;set; }
[DataMember]
public string Address { get;set; }
[DataMember]
public List<Location> Locations { get;set; }
}
}
This is all very straightforward: DTO.Order is what I am returning from my endpoint and Entities.Order is what I am using internally (I am using DI / IOC) for business logic, data operations, etc. Since my business layer returns types from the Entities namespace, but the endpoint returns types from the DTO namespace I wrote a small mapping method that will take one type and map it to another type like so:
public TTarget MapObject<TSource, TTarget>(TSource source, TTarget target)
where TSource : class
where TTarget : class
{
foreach (var prop in source.GetType().GetProperties())
{
var targetProp = target.GetType().GetProperty(prop.Name, BindingFlags.Public | BindingFlags.Instance);
if(targetProp == null || !targetProp.CanWrite) continue;
if (prop.PropertyType.GetGenericTypeDefinition() == typeof (IList<>))
{
??
}
else{ targetProp.SetValue(target, prop.GetValue(source)); }
}
return target;
}
I then call this method like so:
factory.MapObject(Entities.DealerOrder, new GTO.DealerOrder())
where Entities.DealerOrder represents an instantiated object that contains data.
Everything works fine until I get to the property of type IList and I am at a loss at how to convert the IList to List. I know what needs to happen but all of the documentation I have read thus far hasn't pointed me in the right direction.
The pseudo is
if (prop.PropertyType.GetGenericTypeDefinition() == typeof (IList<>))
{
var lst = new List<type of targetProp>()
foreach(var val in prop.GetValue())
{
var item = new Location() (I have to figure out this initialization based on the List type of targetProp. In this case it would be List<Location>)
var retval = MapObject(val, item);
lst.Add(retval);
}
targetProp.SetValue(target, lst);
}
I am not sure if what I want to do is even possible. I know that Generics and Reflection don't mix well so if there is a solution it might be overly complex for what I am really trying to accomplish. If worse comes to worse I can put a static method on each of my DTO's that will accept the source type as a parameter and return an instance of the DTO, but I want to avoid having to manually map the fields from the Entity to the DTO if at all possible.
Any help is greatly appreciated.
You can use targetProp.GetGenericArguments()[0]; to get the type of item you want to map your collection content to.
You can use Activator.CreateInstance to create List<T> with T known at runtime at not at compile time.
You can use Activator.CreateInstance to create instance of the type you want to map to.
You can't rely on type inference when calling MapObject anymore. You need to create proper generic method via reflection here too, and call it.
You can't simply call Add on the list, because you don't know what kind of list it is. You can cast it to ICollection and call Add on it instead.
Can't you just use something like AutoMapper? Those are problems people already solved, why don't you use their work?
I have a series of static methods to modify a collection then return the modified collection:
private static IEnumerable<Invoice> ResolveProxies(IEnumerable<Invoice> e) {
// do something to e
return e;
}
private static IEnumerable<Person> ResolveProxies(IEnumerable<Person> e) {
// do something to e
return e;
}
In another part of the application there is a method to decide if a collection is of a certain type, so that it can be converted to that type and have its corresponding ResolveProxies method called:
public static GridModel<T> ToGridModel<T>(this GridModel gridModel) {
// gridModel.Data is just IEnumerable
var collection = gridModel.Data as IEnumerable<T> ?? new List<T>();
return new GridModel<T> {
Data = EvaluateDynamicProxies(collection),
Total = gridModel.Total
};
}
private static IEnumerable<T> EvaluateProxies<T>(IEnumerable<T> collection) {
if (collection is IEnumerable<Invoice>) {
var enumeration = (collection as IEnumerable<Invoice>);
return ResolveProxies(enumeration) as IEnumerable<T>;
}
if (collection is IEnumerable<Person>) {
var enumeration = (collection as IEnumerable<Person>);
return ResolveProxies(enumeration) as IEnumerable<T>;
}
// proxy resolution isn't needed so return the unchanged collection
return collection;
}
Having such repetitive conditional logic is bad code smell. I'm struggling to come up with some way to mark particular types so that I know they have a corresponding proxy resolver method. Something like this perhaps:
public interface IProxyResolver<out T> where T:IEnumerable<T> {
T ResolveProxies();
}
But how would I use this? In effect I need a way to ask the compiler:
Does T have a matching ResolveProxies method?
What is the name of the class or method that resolves proxies for T so that I can get an instance of it and call it?
You could use an inversion of control (IOC) framework. For example, my team uses Castle Windsor. You can register services (usually interfaces) and types that provide the services. It has some nice generics resolution, so you can do things like this:
interface IProxyResolver<T> { /* whatever */ }
class ProxyResolver<T> : IProxyResolver<T> { /* ... */ }
class PersonProxyResolver : ProxyResolver<Person> { }
class InvoiceProxyResolver : ProxyResolver<Invoice> { }
then, you can summon these types like this:
void SomeMethodThatNeedsAProxyResolver<T>(T obj)
{
var resolver = ioc.Resolve<IProxyResolver<T>>();
//...
}
If you've regsitered the classes above, when T is Person or Invoice, you get the correct non-generic subclass of ProxyResolver; if it is any other type, you get the default generic superclass. Of course, you can structure things differently; if you need a specific proxy resolver for every type, that's possible too.
How about using a custom attribute? This is how custom serializers are selected, etc.
You'd start by defining the Attribute class:
public class ProxyResolverAttribute : Attribute {
public Type ResolverType { get; set; }
public ProxyResolver(Type resolverType) { ResolverType = resolverType; }
}
and then put that on the type contained, e.g.
[ProxyResolver(TypeOf(InvoiceProxyResolver))]
public class Invoice ... { ... }
then use reflection to see if the generic type used in the collection specifies a proxy resolver type:
// Untested, beware of bugs
var enumerationGenericType = enumeration.GetType().GetGenericArguments().FirstOrDefault();
var resolverAttribute = enumerationGenericType.GetType().GetCustomAttributes(TypeOf(ProxyResolverAttribute)).FirstOrDefault();
if (resolverAttribute != null) {
var resolverType = resolverAttribute.ResolverType;
// instanciate something of resolverType here
}
EDIT: Reading the comments, if you don't want to apply the attributes to the contained objects, I'd suggest creating custom classes which inherit List and apply the attribute there, e.g.
[ProxyResolver(TypeOf(InvoiceProxyResolver))]
public class InvoiceList : List<Invoice>
In NHibernate 3.0 Cookbook, there is a sample implementation for a base Entity type. The equals is implemented like this:
public abstract class Entity<TId>
{
public virtual TId Id { get; protected set; }
public override bool Equals(object obj)
{
return Equals(obj as Entity<TId>);
}
private static bool IsTransient(Entity<TId> obj)
{
return obj != null && Equals(obj.Id, default(TId));
}
private Type GetUnproxiedType()
{
return GetType();
}
public virtual bool Equals(Entity<TId> other)
{
if (other == null) return false;
if (ReferenceEquals(this, other)) return true;
if (!IsTransient(this) && !IsTransient(this) && Equals(Id, other.Id))
{
var otherType = other.GetUnproxiedType();
var thisType = GetUnproxiedType();
return thisType.IsAssignableFrom(otherType) ||
otherType.IsAssignableFrom(thisType);
}
return false;
}
}
The reason for the GetUnproxiedType() method is this: There is an abstract base class Product, a concrete class Book which inherits from Product and a dynamic proxy class ProductProxy used by NHibernate for lazy loading. If a ProductProxy representing a Book and a concrete Book have the same Ids, they should be treated as equal. However I don't really see why calling GetType() on a ProductProxy instance should return Product in this case, and how it helps. Any ideas?
I actually went ahead and wrote to the author of the book about this code. It turns out this is due to how the proxy wrapping works. Here is his response:
"If you don't understand how the proxy frameworks work, the idea can seem magical.
When NHibernate returns a proxy for the purposes of lazy loading, it returns a proxy instance inherited from the actual type. There are a few members we can access without forcing a load from the database. Among these are proxy's Id property or field, GetType(), and in some circumstances Equals() and GetHashCode(). Accessing any other member will force a load from the database.
When that happens, the proxy creates an internal instance. So, for example, a lazy loaded instance of Customer (CustomerProxy102987098721340978), when loaded, will internally create a new Customer instance with all of the data from the database. The proxy then does something like this:
public overrides string Name
{
get {
return _loadedInstance.Name;
}
set { _loadedInstance.Name = value; }
}
Incidentally, it's this overriding that requires everything to be virtual on entities that allow lazy loaded.
So, all calls to the Name property on the proxy are relayed to the internal Customer instance that has the actual data.
GetUnproxiedType() takes advantage of this. A simple call to GetType() on the proxy will return typeof(CustomerProxy02139487509812340). A call to GetUnproxiedType() will be relayed to the internal customer instance, and the internal customer instance will return typeof(Customer)."
With current (v5.x) NHibernate proxy factories (static or dynamic, static being available since v5.1), this pattern is actually broken. The v5 built-in proxy factories do not intercept private methods.
And I think that was already the case for v4 ones.
For this pattern to work with current built-in proxy factories, GetUnproxiedType should be virtual (so not private by the way, but protected).
Otherwise, use NHibernateUtil.GetClass, which is meant for this and does not rely on brittle tricks. Its documentation warns it will initialize the proxy by side effect, but anyway the GetUnproxiedType trick must do the same for working.
Of course using NHibernateUtil.GetClass means having a direct dependency to NHibernate in a domain model base class. But depending on an implementation trick specific to an external (from the domain viewpoint) library implementation is no better in my opinion.
Moreover, some changes may cause the GetUnproxiedType trick to be even more broken in the future, like some ideas for reducing the number of cases causing a proxy to get initialized when it could be avoided. (See here by example.)
If you really want a GetUnproxiedType method not depending on a direct NHibernate reference, I think the only theoretically "safe" solution is to have it abstract and overridden in each concrete entity class for yielding typeof(YourEntityClass). But in practice, it would be cumbersome and error-prone (bad copy-paste for creating a new entity, forgetting to change that method...), while the abstract part won't help in case some concrete entity classes are further specialized through inheritance.
Another trick could be, from the type obtained by GetType, to check to which assembly it belongs (the proxy type will not belong to one of your assemblies), for searching the first type in the hierarchy belonging to your domain model assembly(ies).
Note that if the proxy is a proxy of a base class, not of a concrete class, and your helper method is set as private, it will yield the base class type, without initializing the proxy. Performance-wise, this is better. While a virtual GetUnproxiedType simply returning GetType would return the concrete class type with current proxy factories, but it would also initialize the proxy.
We use NH 2 and this example did not work for us. (It FAILED to unproxy the type and left proxy type, see below).
It said that 2 entities with the same id are not equal, when one of them is proxy(of COrganization) and other is not(DOrganization).
When we had a hierarchy:
class Organization
class AOrganization : Organization
class COrganization : Organization
{
public virtual COrganization GetConcrete()
{
return null;
}
}
class DOrganization : COrganization
{
public virtual COrganization GetConcrete()
{
return this;
}
}
AOrganization aOrganization;
COrganization cOrganization;
contract = new CContract(aOrganization, cOrganization as COrganization); //(COrganization)(cOrganization.GetConcrete()),
So CContract has a field of type COrganization. With a setter
public class Contract: Entity <short>
{
public virtual COrganization COrganization
{
get { return cOrganization; }
protected internal set
{
if (cOrganization != null && value != cOrganization) // != calls ==, which calls Equals, which calls GetUnproxiedType()
throw new Exception("Changing organization is not allowed.");
}
cOrganization = value;
}
}
private COrganization cOrganization;
}
We constructed new Contract, its constructor set the COrganization field pointing to some organization. Then we called UnitOfWork.Commit, NH tried to set COrganization field again (with the same id), GetUnproxiedType worked incorrectly, new and old values were recognized as non-equal, and exception was thrown...
Here is the place where error showed up:
var otherType = other.GetUnproxiedType();
var thisType = GetUnproxiedType();
return thisType.IsAssignableFrom(otherType) ||
otherType.IsAssignableFrom(thisType);
In debugger: otherType == COrganizationProxy - GetUnproxiedType failed...
thisType == DOrganization
COrganizationProxy and DOrganization both inherit COrganization.
So they are not IsAssignableFrom for each other...
Why does this example work for you?
Maybe because we have NH 2.0 or 2.1?
Or because of simple "cOrganization as COrganization" instead of "(COrganization)(cOrganization.GetConcrete())"?
Or because we have implementation of ==, != and Equals not only in Entity, but in Organization too?
public abstract class Organization : Entity<int>
{
public override bool Equals(object obj)
{
return base.Equals(obj);
}
public override int GetHashCode()
{
return base.GetHashCode();
}
public static bool operator ==(Organization object1, Organization object2)
{
return AreEqual(object1, object2);
}
public static bool operator !=(Organization object1, Organization object2)
{
return AreNotEqual(object1, object2);
}
}
public abstract class Entity<TId>
{
public virtual TId Id { get; /*protected*/ set; }
public override bool Equals(object obj)
{
return Equals(obj as Entity<TId>);
}
private static bool IsTransient(Entity<TId> obj)
{
return obj != null &&
Equals(obj.Id, default(TId));
}
private Type GetUnproxiedType()
{
return GetType();
}
public virtual bool Equals(Entity<TId> other)
{
if (other == null)
return false;
if (ReferenceEquals(this, other))
return true;
if (!IsTransient(this) &&
!IsTransient(other) &&
Equals(Id, other.Id))
{
var otherType = other.GetUnproxiedType();
var thisType = GetUnproxiedType();
return thisType.IsAssignableFrom(otherType) ||
otherType.IsAssignableFrom(thisType);
}
return false;
}
public override int GetHashCode()
{
if (Equals(Id, default(TId)))
return base.GetHashCode();
return Id.GetHashCode();
}
/// This method added by me
/// For == overloading
protected static bool AreEqual<TEntity>(TEntity entity1, TEntity entity2)
{
if ((object)entity1 == null)
{
return ((object)entity2 == null);
}
else
{
return entity1.Equals(entity2);
}
}
/// This method added by me
/// For != overloading
protected static bool AreNotEqual<TEntity>(TEntity entity1, TEntity entity2)
{
return !AreEqual(entity1, entity2);
}
}
I have a layer of business-level objects and a layer of contract-level objects in a WCF service application. The business layer objects I'm referring to are just entity or POCO objects that I'm using to hold data. The contract-level objects I'm referring to are the objects that make up the WSDL my clients see (also POCOs).
When I return data from my WCF service to a client the the request parameters are hydrated from one or more of my contract layer objects into XML and forwarded on.
I'm trying to create a class that sits outside of the contract and business layers that will translate objects from one layer to another. So, for instance, in the contract layer I would have a class like:
public class Person
{
public string Name { get; set;};
}
I could also have an identical class (or it could be different) in the business layer whose property would be mapped to the property in this class.
I then have a class that executes code that looks like this:
public Contract.Person TranslatePerson(Business.Person person)
{
Contract.Person result = new Contract.Person();
result.Name = person.Name;
return result;
}
This all works as expected. However, one of the requirements of this translator service is to insulate the business layer from changes in the contract layer and, one of the requirements of this layer is to allow different versions of the contract layer to exist simultaneously to support backwards compatibility for SOAP clients. For instance if in v2 of the service I want to add last name to the person class and change Name to FirstName so that my SOAP clients can now see both data points I will have something like this:
// remains for backwards compatibility for V1 clients
namespace Contract.V1
{
public class Person
{
public string Name { get; set;};
}
}
namespace Contract.V2
{
public class Person
{
public string FirstName { get; set;};
public string LastName { get; set;};
}
}
Now when I need to send back a V2 Person to the client I want to map FirstName to FirstName from the business object and LastName to LastName. However, if I need to send back a V1 Person I will map FirstName to Name and just drop LastName.
The architecture I created for my translation layer is thusly:
public class V1Translator
{
public virtual Contract.V1.Person TranslatePerson(Business.Person person)
{
Contract.V1.Person result = new Contract.V1.Person();
result.Name = person.Name;
return result;
}
}
public class V2Translator : V1Translator
{
public override Contract.V2.Person TranslatePerson(Business.Person person)
{
Contract.V2.Person result = new Contract.V2.Person();
result.Name = person.Name;
return result;
}
}
This saves me a lot of time because I might have 100 different translation methods in V1Translator but I may only have to override 2 or 3 in V2Translator because there may be only a few objects that change in the different layers. I am also instantiating the appropriate Translator class using a factory. In this manner I can just call TranslatePerson on my special TranslationService class and have it figure out which Translator to use. This, however, is also where the problem comes in. I can't override the method in the base class because the return types are different. Even though they are both Contract Person objects, they are in different namespaces. I'm having difficulty getting passed this.
Can someone help me create an elegant solution to this problem?
Thanks
Check out AutoMapper, it's excellent at reducing the amount of manual mapping code you'll need to write in scenarios like this.
I wrote these 2 extension methods to accomplish this exact problem, they may give you a good starting point to solve your issue!
public static Y To<X, Y>(this X source) where X : IActiveRecord where Y: class
{
try
{
Y target = Activator.CreateInstance(typeof(Y)) as Y;
BindingFlags memberAccess = BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.SetProperty;
PropertyInfo[] targetProperties = target.GetType().GetProperties(memberAccess);
foreach (MemberInfo Field in targetProperties)
{
string name = Field.Name;
if (Field.MemberType == MemberTypes.Property)
{
PropertyInfo targetProperty = Field as PropertyInfo;
PropertyInfo sourceProperty = source.GetType().GetProperty(name, memberAccess);
if (sourceProperty == null) { continue; }
if (targetProperty.CanWrite && sourceProperty.CanRead)
{
object targetValue = targetProperty.GetValue(target, null);
object sourceValue = sourceProperty.GetValue(source, null);
if (sourceValue == null) { continue; }
if (targetProperty.PropertyType.FullName == sourceProperty.PropertyType.FullName)
{
object tempSourceValue = sourceProperty.GetValue(source, null);
targetProperty.SetValue(target, tempSourceValue, null);
}
}
}
}
return target;
}
// it's important to return null if there are any errors.
catch { return null; }
}
public static IList<Y> To<X, Y>(this BindingListEx<X> collection) where X : IActiveRecord where Y : class
{
IList<Y> returnList = new List<Y>();
foreach (X item in collection)
returnList.Add(item.To<X,Y>());
return returnList;
}
I use this to convert subsonic 2 entities (hence the IActiveRecord constraint) to my own POCO's