Getting duplicated entries of interfaces in a Dictionary - c#

So i have an interface named IResource that consist of those 5 properties as readonly but since I am adding those to a Dictionary<IResource, int> i need a way to compare two IResource so i don't have duplicates in the Dictionary. Is there a way for me to add a default Equals(object obj) to every IResource?
I already added an Equals Override to the Wood class and it solved the problem but i would have to add a Equals(object obj) in every class that implements the IResource.
public class Wood : IResource
{
public string Package => "Core";
public string Family => "Wood";
public string Name => "Wood";
public bool IsFractal => false;
public ResourceType Type => ResourceType.Natural;
}
PS:I have an override of the Add(IResource key, uint value) method to the dictionary to check if the IResource already exists.
public new void Add(IResource key, uint value)
{
if (base.ContainsKey(key))
base[key] += value;
else
base.Add(key, value);
}
Right now when i add a IResource interface to the dictionary, it always adds a new entry.

You can move your comparison to a base class and override Equals and GetHashCode there. Just add any members you want to use in the comparison to the abstract class and include them in the equity comparison.
For example:
public enum ResourceType { Natural }
public interface IResource
{
public string Name { get; }
public ResourceType ResourceType { get; }
}
public abstract class Resource
{
public abstract string Name { get; }
public abstract ResourceType ResourceType { get; }
// other properties that you want to use for your resource comparision
public override bool Equals(object obj)
=> obj is Resource r && Name == r.Name && ResourceType == r.ResourceType;
public override int GetHashCode() => (Name, ResourceType).GetHashCode();
}
public class Wood : Resource, IResource
{
public override string Name => "Wood";
public override ResourceType ResourceType => ResourceType.Natural;
// ... other properties
}

While it's certainly possible to create an abstract base class - as others have pointed out - it's really not a great idea. You're creating a dependency that any class that implements IResource must also implement equality as you've defined it for IResource. And that might be fine or it might make it hard to maintain and lead to bugs.
The framework is designed to handle this situation by allowing you to customize how the dictionary does comparisons. It does this by using IEqualityComparer.
Here's an example for your IResource interface:
public class ResourceComparer : IEqualityComparer<IResource>
{
public bool Equals([AllowNull] IResource x, [AllowNull] IResource y)
{
if (null == x && null == y)
return true;
if (null == x || null == y)
return false;
return x.Package.Equals(y.Package) &&
x.Family.Equals(y.Family) &&
x.Name.Equals(y.Name) &&
x.IsFractal.Equals(y.IsFractal) &&
x.Type.Equals(y.Type);
}
public int GetHashCode([DisallowNull] IResource obj)
{
HashCode hash = new HashCode();
hash.Add(obj.Package);
hash.Add(obj.Family);
hash.Add(obj.Name);
hash.Add(obj.IsFractal);
hash.Add(obj.Type);
return hash.ToHashCode();
}
}
Once you've got that then you can create your dictionary with that comparer. I've used your Wood class and created one other called Metal. Neither has to share a base class or override Equals and GetHashCode.
static void Main(string[] _)
{
var resourceMap = new Dictionary<IResource,uint>(new ResourceComparer());
var resources = new IResource[] { new Wood(), new Metal(),
new Wood(), new Wood() };
foreach (var r in resources)
{
if (resourceMap.TryGetValue(r, out var count))
resourceMap[r] = count + 1;
else
resourceMap.Add(r, 1);
}
Console.WriteLine(resourceMap[new Wood()]);
Console.WriteLine(resourceMap[new Metal()]);
}
Here's the simple POCO style metal class:
public class Metal : IResource
{
public string Package => "Core";
public string Family => "Metal";
public string Name => "Metal";
public bool IsFractal => false;
public ResourceType Type => ResourceType.ManMade;
}

You can create an abstract class that implements IResource. Use that class and override Equals and GetHashCode.
public abstract class Resource : IResource
{
//make all your interface properties abstract
public abstract string Package { get; }
public abstract string Family { get; }
public abstract string Name { get; }
public abstract bool IsFractal { get; }
public abstract ResourceType Type { get; }
public override bool Equals(object obj)
{
if (!(obj is Resource resource)) return false;
return ReferenceEquals(this, resource) ||
Package == resource.Package &&
Family == resource.Family &&
Name == resource.Family &&
IsFractal == resource.IsFractal &&
Type == resource.Type;
}
public override int GetHashCode()
{
return HashCode.Combine(Package, Family, Name, IsFractal, Type);
}
}
Then make all your resources implement the abstract class Resource
public class Wood : Resource
{
public override string Package => "Core";
public override string Family => "Wood";
public override string Name => "Wood";
public override bool IsFractal => false;
public override ResourceType Type => ResourceType.Natural;
}
public class Rock : Resource
{
public override string Package => "Core";
public override string Family => "Rock";
public override string Name => "Rock";
public override bool IsFractal => false;
public override ResourceType Type => ResourceType.Natural;
}
This will give you the behavior you expect.

Related

How to use PropertyGrid to allow editing properties without a setter?

By default, PropertyGrid only allowed editing properties with public setter. I'd like to allow editing of properties without a setter.
For example:
class A {
public int X {get;set}
public int Y {get;}
}
In the example above, only X will be editable. Y will be displayed but grayed out. How can I make Y editable?
Note: making a private backing field would be OK. For example:
class A {
public int X {get;set}
private int y;
public int Y {get => y; }
}
You can build a wrapper/proxy class based on the ICustomTypeDescriptor Interface that allows you to tweak properties at runtime.
This is how you could use it:
var a = new A();
// build a proxy
var proxy = new Proxy(a);
// tweak any properties
proxy.Properties["Y"].IsReadOnly = false;
// you can also tweak attributes
proxy.Properties["Y"].Attributes.Add(new CategoryAttribute("R/O -> R/W"));
proxy.Properties["Y"].Attributes.Add(new DescriptionAttribute("This works"));
// handle property change
propertyGrid1.PropertyValueChanged += (s, e) =>
{
if (e.ChangedItem.PropertyDescriptor.Name == "Y")
{
a.Y = (int)e.ChangedItem.Value;
}
};
// select the proxy instead of the original instance
propertyGrid1.SelectedObject = proxy;
And here is the result
...
class A
{
public int X { get; set; }
public int Y { get; internal set; }
}
...
public class Proxy : ICustomTypeDescriptor
{
public Proxy(object instance)
{
if (instance == null)
throw new ArgumentNullException(nameof(instance));
Instance = instance;
Properties = TypeDescriptor.GetProperties(instance).OfType<PropertyDescriptor>().Select(d => new ProxyProperty(instance, d)).ToDictionary(p => p.Name);
}
public object Instance { get; }
public IDictionary<string, ProxyProperty> Properties { get; }
public AttributeCollection GetAttributes() => TypeDescriptor.GetAttributes(Instance);
public string GetClassName() => TypeDescriptor.GetClassName(Instance);
public string GetComponentName() => TypeDescriptor.GetComponentName(Instance);
public TypeConverter GetConverter() => TypeDescriptor.GetConverter(Instance);
public EventDescriptor GetDefaultEvent() => TypeDescriptor.GetDefaultEvent(Instance);
public object GetEditor(Type editorBaseType) => TypeDescriptor.GetEditor(Instance, editorBaseType);
public EventDescriptorCollection GetEvents() => TypeDescriptor.GetEvents(Instance);
public EventDescriptorCollection GetEvents(Attribute[] attributes) => TypeDescriptor.GetEvents(Instance, attributes);
public PropertyDescriptor GetDefaultProperty() => TypeDescriptor.GetDefaultProperty(Instance);
public PropertyDescriptorCollection GetProperties() => new PropertyDescriptorCollection(Properties.Values.Select(p => new Desc(this, p)).ToArray());
public PropertyDescriptorCollection GetProperties(Attribute[] attributes) => GetProperties();
public object GetPropertyOwner(PropertyDescriptor pd) => Instance;
private class Desc : PropertyDescriptor
{
public Desc(Proxy proxy, ProxyProperty property)
: base(property.Name, property.Attributes.ToArray())
{
Proxy = proxy;
Property = property;
}
public Proxy Proxy { get; }
public ProxyProperty Property { get; }
public override Type ComponentType => Proxy.GetType();
public override Type PropertyType => Property.PropertyType ?? typeof(object);
public override bool IsReadOnly => Property.IsReadOnly;
public override bool CanResetValue(object component) => Property.HasDefaultValue;
public override object GetValue(object component) => Property.Value;
public override void ResetValue(object component) { if (Property.HasDefaultValue) Property.Value = Property.DefaultValue; }
public override void SetValue(object component, object value) => Property.Value = value;
public override bool ShouldSerializeValue(object component) => Property.ShouldSerializeValue;
}
}
public class ProxyProperty
{
public ProxyProperty(string name, object value)
{
if (name == null)
throw new ArgumentNullException(nameof(value));
Name = name;
Value = value;
Attributes = new List<Attribute>();
}
public ProxyProperty(object instance, PropertyDescriptor descriptor)
{
if (descriptor == null)
throw new ArgumentNullException(nameof(descriptor));
Name = descriptor.Name;
Value = descriptor.GetValue(instance);
var def = descriptor.Attributes.OfType<DefaultValueAttribute>().FirstOrDefault();
if (def != null)
{
HasDefaultValue = true;
DefaultValue = def.Value;
}
IsReadOnly = (descriptor.Attributes.OfType<ReadOnlyAttribute>().FirstOrDefault()?.IsReadOnly).GetValueOrDefault();
ShouldSerializeValue = descriptor.ShouldSerializeValue(instance);
Attributes = descriptor.Attributes.Cast<Attribute>().ToList();
PropertyType = descriptor.PropertyType;
}
public string Name { get; }
public object Value { get; set; }
public object DefaultValue { get; set; }
public bool HasDefaultValue { get; set; }
public bool IsReadOnly { get; set; }
public bool ShouldSerializeValue { get; set; }
public Type PropertyType { get; set; }
public IList<Attribute> Attributes { get; }
}
There is a way to do this, but it is absurdly complex;
you create a custom TypeDescriptionProvider and link it to the type, or implement ICustomTypeDescriptor in the type, and
you create a custom PropertyDescriptor that knows how to edit the field in the GetValue and SetValue
you create a custom TypeDescriptor that echos the standard property descriptors for most things, and your new property descriptor in this case
In all seriousness, though; please don't do this! Just make the property accessible in the first place. If it isn't a settable property, you shouldn't be trying to set it.
based on the comments it sounds like what you actually need is "popsicle immutability"; consider:
class Foo {
private bool _frozen;
public void Freeze() => _frozen = true;
protected void ThrowIfFrozen() {
if (_frozen) throw new InvalidOperationException(
"The object cannot be changed once Freeze has been called");
}
private int _x, _y;
public int X {
get => _x;
set {
if (value != _x) {
ThrowIfFrozen();
_x = value;
}
}
}
public int Y {
get => _y;
set {
if (value != _y) {
ThrowIfFrozen();
_y = value;
}
}
}
}

How to compare and sort subclasses?

For example I have these class and subclasses.
class Program
{
static void Main(string[] args)
{
var animals = new List<Animal> { new Wolf {kills = 5},
new Rabbit {name = "Uncle John"},
new Eagle {eyeCount = 1},
new Wolf {kills = 100},
new Rabbit { name = "Human" } };
animals.Sort();
//Suposted to be: Rabbit(Human), Rabbit(Uncle John), Wolf(5), Wolf(100), Eagle(1)
}
}
enum SortOrder { Rabbit, Wolf, Eagle }
abstract class Animal{}
class Wolf : Animal
{
public int kills = 0; //Marked public for simple initialization
}
class Rabbit : Animal
{
public string name = "Funny Little Guy"; //Marked public for simple initialization
}
class Eagle : Animal
{
public byte eyeCount = 2; //Marked public for simple initialization
}
I want to sort list of animals. 1)Sort among the other objects of same type (sort Wolves by kill, rabbits by name, etc) 2) Sort groups of subclasses in "SortOrder", so Rabbits goes first in the list and Eagles last.
I had tried make this by implementing IComparable<Animal>, IComparable<Wolf>, IComparable<Rabbit>, IComparable<Eagle> interfaces, but this lead me to nowhere, because I couldn't make this work and even though I could, adding 1 more subclass cause a lot code work.
This is my trying:
abstract class Animal : IComparable<Animal>, IComparable<Wolf>, IComparable<Rabbit>, IComparable<Eagle>
{
public abstract int CompareTo(Animal other);
public abstract int CompareTo(Wolf other);
public abstract int CompareTo(Rabbit other);
public abstract int CompareTo(Eagle other);
}
class Wolf : Animal
{
public int kills = 0; //Marked public for simple initialization
public override int CompareTo(Animal other) => other.CompareTo(this);
public override int CompareTo(Wolf other) => kills.CompareTo(kills);
public override int CompareTo(Rabbit other) => SortOrder.Wolf.CompareTo(SortOrder.Rabbit);
public override int CompareTo(Eagle other) => SortOrder.Wolf.CompareTo(SortOrder.Eagle);
}
But by doing this way I getting reverse order, and As I said its hard to add new subclasses.
So what is efficient way to make this kind of comparison?
To minimize adding new code and force new class to add to the hierarchy I would do this kind of design:
First, I would implement IComparable for each concrete animal type. This is simple. Second, I would add SortOrder OrderType property to the abstract class and implement it in each concrete instance. This would force whoever extends the class to re-evaluate the enum and probably add new value to it. Then, the main compare function would first check this property. If not equal, then return the comparison between types. If equal, just call compare on the two instances, because it can be safely assumed they are of same type.
Implemented it here. I actually had to use reflection, because there is no other way to call concrete comparer. But it seems to work pretty nicely, as long as the actual type corresponds to returned enum.
enum SortOrder { Rabbit, Wolf, Eagle }
abstract class Animal : IComparable<Animal>
{
public abstract SortOrder OrderType { get; }
public int CompareGeneric(Animal x, Animal y)
{
// use reflection to call comparer on concrete animal type
var comparerType = typeof(IComparable<>).MakeGenericType(x.GetType());
var compareMethod = comparerType.GetMethod("CompareTo");
return (int)compareMethod.Invoke(x, new object[] { y });
}
public int Compare(Animal x, Animal y)
{
// clever hack to compare the enums
var diff = x.OrderType - y.OrderType;
if (diff != 0)
return diff;
return CompareGeneric(x, y);
}
public int CompareTo(Animal other)
{
return Compare(this, other);
}
}
class Wolf : Animal, IComparable<Wolf>
{
public override SortOrder OrderType { get { return SortOrder.Wolf; } }
public int kills = 0; //Marked public for simple initialization
public int CompareTo(Wolf other)
{
return this.kills.CompareTo(other.kills);
}
}
class Rabbit : Animal, IComparable<Rabbit>
{
public override SortOrder OrderType { get { return SortOrder.Rabbit; } }
public string name = "Funny Little Guy"; //Marked public for simple initialization
public int CompareTo(Rabbit other)
{
return this.name.CompareTo(other.name);
}
}
class Eagle : Animal, IComparable<Eagle>
{
public override SortOrder OrderType { get { return SortOrder.Eagle; } }
public byte eyeCount = 2; //Marked public for simple initialization
public int CompareTo(Eagle other)
{
return this.eyeCount.CompareTo(other.eyeCount);
}
}
I think you can implement IComparable with Animal class and use a read only SortOrder enum property as Euphoric mentioned.
Then in each class you can override CompareTo method to compare each species with their kind.
public abstract class Animal : IComparable
{
public abstract SortOrder SortOrder { get; }
public virtual int CompareTo(object obj)
{
Animal rightValue = (Animal)obj;
return this.SortOrder < rightValue.SortOrder ? -1
: this.SortOrder > rightValue.SortOrder ? 1 : 0;
}
}
public class Wolf : Animal
{
public override SortOrder SortOrder { get { return SortOrder.Wolf; } }
public int kills = 0; //Marked public for simple initialization
public override int CompareTo(object obj)
{
if (obj is Wolf)
{
Wolf rightValue = (Wolf)obj;
return this.kills < rightValue.kills ? -1
: this.kills > rightValue.kills ? 1 : 0;
}
else
{
return base.CompareTo(obj);
}
}
}
public class Rabbit : Animal
{
public override SortOrder SortOrder { get { return SortOrder.Rabbit; } }
public string name = "Funny Little Guy"; //Marked public for simple initialization
public override int CompareTo(object obj)
{
if (obj is Rabbit)
{
Rabbit rightValue = (Rabbit)obj;
return String.Compare(this.name, rightValue.name);
}
else
{
return base.CompareTo(obj);
}
}
}
public class Eagle : Animal
{
public override SortOrder SortOrder { get { return SortOrder.Eagle; } }
public byte eyeCount = 2; //Marked public for simple initialization
public override int CompareTo(object obj)
{
if (obj is Eagle)
{
Eagle rightValue = (Eagle)obj;
return this.eyeCount < rightValue.eyeCount ? -1
: this.eyeCount > rightValue.eyeCount ? 1 : 0;
}
else
{
return base.CompareTo(obj);
}
}
}
I would add an SortKey and the ICompareable Interface to your Animal class and implement the logic in derived class.
abstract class Animal : IComparable<Animal>
{
public abstract int SortKey { get; }
public abstract int CompareTo(Animal other);
}
class Wolf : Animal
{
public int kills = 0; //Marked public for simple initialization
public override int SortKey { get { return 100; } }
public override int CompareTo(Animal other)
{
if (other.SortKey != SortKey)
{
return SortKey.CompareTo(other.SortKey);
}
var otherWolf = other as Wolf;
if (otherWolf == null)
{
return -1;
}
return kills.compareTo(otherWolf.kills);
}
}
Consider using an IComparer across types; and implement IComparable for ordering within the specific type. The Comparer would call the Comparable only for same-type comparisons.
Advantage(s):
None of the types needs to know it's "relative" sorting key between types. In addition the base type is not 'dirtied' with an additional field. (Although there is nothing preventing putting the ordering in such a 'SortKey'-field.)
The rules for ordering types of animals is isolated in one location, the Comparer.
The rule for ordering within an animal type is already
handled by the IComparable and can be overridden/specialized
for each type.
Disadvantage(s):
The collection / ordering operation needs to use the Comparer
Comparer adds "hidden" logic that may need to be updated for additional types. (This is only required if not using a 'SortKey'-like approach in a base type.)
Using a separate IComparaer/IComparable approach is a more generic form of using a 'SortKey' field, with the additional ordering mixed into the IComparable, because such a field could be used by such a IComparer implementation.
I would solve your Problem with Linq
using System.Collections.Generic;
using System.Linq;
public enum SortOrder
{
Rabbit,
Wolf,
Eagle
}
public class Program
{
public static void Main(string[] args)
{
var animals = (new List<Animal> { new Wolf {Kills = 5},
new Rabbit {Name = "Uncle John"},
new Eagle {EyeCount = 1},
new Wolf {Kills = 100},
new Rabbit { Name = "Human" } })
.OrderBy(x => x.SortOrder)
.ThenBy(x => x.Classifier);
//Suposted to be: Rabbit(Human), Rabbit(Uncle John), Wolf(5), Wolf(100), Eagle(1)
}
}
public abstract class Animal
{
public abstract object Classifier { get; }
public string Name { get; set; }
public SortOrder SortOrder { get; set; }
}
public class Eagle : Animal
{
public Eagle()
{
this.SortOrder = SortOrder.Eagle;
}
public override object Classifier
{
get { return this.EyeCount; }
}
public byte EyeCount { get; set; }
}
public class Rabbit : Animal
{
public Rabbit()
{
this.Name = "Funny Little Guy";
this.SortOrder = SortOrder.Rabbit;
}
public override object Classifier
{
get { return this.Name; }
}
}
public class Wolf : Animal
{
public Wolf()
{
this.Name = "Funny Little Guy";
this.SortOrder = SortOrder.Wolf;
}
public override object Classifier
{
get { return this.Kills; }
}
public int Kills { get; set; }
}

Removed object property duplication from list

This is my object:
public class MyObject
{
public int id { get; set; }
public string fileName { get; set; }
public string browser { get; set; }
public string protocol { get; set; }
public string family { get; set; }
}
and i have a list of my object:
List<Capture> list = db.Captures.Where(x => x.family == "Web").ToList();
What i want to do is get new list that removed the duplicate protocol.
for example if i have in my list 10 object and 9 of them with protocol DOC and 1 PDF i want a new list with only 2 object DOC and 1 PDF
There are several ways to do this, depending on how you generally want to use the instances of your MyObject class.
The easiest one is implementing the IEquatable<T> interface so as to compare only the protocol fields:
public class MyObject : IEquatable<MyObject>
{
public sealed override bool Equals(object other)
{
return Equals(other as MyObject);
}
public bool Equals(MyObject other)
{
if (other == null) {
return false;
} else {
return this.protocol == other.protocol;
}
}
public override int GetHashCode()
{
return protocol.GetHashCode();
}
}
You can then call Distinct before converting your enumerable into a list.
Alternatively, you can use the Distinct overload that takes an IEqualityComparer.
The equality comparer would have to be an object that determines equality based on your criteria, in the case described in the question, by looking at the protocol field:
public class MyObjectEqualityComparer : IEqualityComparer<MyObject>
{
public bool Equals(MyObject x, MyObject y)
{
if (x == null) {
return y == null;
} else {
if (y == null) {
return false;
} else {
return x.protocol == y.protocol;
}
}
}
public int GetHashCode(MyObject obj)
{
if (obj == null) {
throw new ArgumentNullException("obj");
}
return obj.protocol.GetHashCode();
}
}
I believe this is the simplest approach: The following will group list by protocol and then get the first instance from each group to produce an enumerable with one instance of each type of protocol.
list.GroupBy(x => protocol, x => x)
.SelectMany(k, v => v.First());
You could either use Distinct, or use the same solution provided here:
Distinct() with lambda?
Select distinct protocols, loop on them and subselect only first object of the same protocol - thus you'll get the list you need.

JsonSerializer calling container Equals override method

First of all had a good look around and understand override/virtual etc. But haven't found any cases specific to my situation - which I'm sure isn't unique. I want to just make sure the implementation I go with is the right implementation. I have the following code setup to demonstrate my issue:
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace Sandpit
{
public class Program
{
static void Main()
{
var fixture = new Fixture
{
Name = "Fixture Name",
Participants = new List<Participant> {new Participant {Name = "Participant Name"}}
};
var writer = new StringWriter(new StringBuilder());
var serializer = new JsonSerializer();
serializer.Converters.Add(new StringEnumConverter());
serializer.Serialize(writer, fixture);
Console.Write(writer.ToString());
Console.ReadKey();
}
}
public class Fixture
{
public string Name { get; set; }
public List<Participant> Participants { get; set; }
public override bool Equals(object obj)
{
var fixture = (Fixture)obj;
return fixture.Name == Name;
}
public override int GetHashCode()
{
return Name.GetHashCode();
}
}
public class Participant
{
public string Name { get; set; }
public override bool Equals(object obj)
{
var participant = (Participant)obj;
return participant.Name == Name;
}
public override int GetHashCode()
{
return Name.GetHashCode();
}
}
}
Now when this runs I get an exception on var fixture = (Fixture)obj;.
Unable to cast object of type
'System.Collections.Generic.List`1[Sandpit.Participant]' to type
'Sandpit.Fixture'.
I don't understand why it is getting into there. And why this breaks the correct implementation of overridden object methods.
I know that I can fix this by doing public new bool Equals(object obj). Am I doing this right? Also these objects are well integrated into the application I am working on, is there likely to be any side effects to making this change?
Many thanks,
Matt
A small change to your Fixture and Participant classes fixes this:
public class Fixture
{
public string Name { get; set; }
public List<Participant> Participants { get; set; }
public override bool Equals(object obj)
{
var fixture = obj as Fixture;
return fixture == null ? false : fixture.Name == Name;
}
public override int GetHashCode()
{
return Name.GetHashCode();
}
}
public class Participant
{
public string Name { get; set; }
public override bool Equals(object obj)
{
var participant = obj as Participant;
return participant == null ? false : participant.Name == Name;
}
public override int GetHashCode()
{
return Name.GetHashCode();
}
}
If you are comparing to an element that's of another type, you can be certain that the two are not equal.

How can I create a Fluent NHibernate Convention that ignores properties that don't have setters

I'm looking for a FluentNH (Fluent NHibernate) convention or configuration that ignores all properties that have no setter:
It would still map these:
public class foo{
public virtual int bar {get; private set;}
}
And omit these:
public class foo{
public virtual int fizz{get;private set;}
public virtual int bar{get {return fizz;}} //<-------
}
You should use a custom mapping configuration
public class DefaultMappingConfiguration : DefaultAutomappingConfiguration
{
public override bool ShouldMap(Member member)
{
return member.CanWrite;
}
}
Usage :
var nhConfiguration = new Configuration().Configure();
var mappingConfiguration = new DefaultMappingConfiguration();
var.fluentConfiguration = Fluently.Configure(nhConfiguration );
.Mappings(m => m.AutoMappings.Add(
AutoMap.AssemblyOf<MappedType>(mappingConfiguration)
));
var sessionFactory = this.fluentConfiguration.BuildSessionFactory();
However, private setters won't get mapped. You should get them as protected
Use this:
public class DefaultMappingConfiguration : DefaultAutomappingConfiguration
{
public override bool ShouldMap(Member member)
{
if (member.IsProperty && !member.CanWrite)
{
return false;
}
return base.ShouldMap(member);
}
}
That should handle the case of no setter and private setter.
I know this is old question but code below do well with private setters.
public override bool ShouldMap(Member member)
{
var prop = member.DeclaringType.GetProperty(member.Name);
bool isPropertyToMap =
prop != null &&
prop.GetSetMethod(true) != null &&
member.IsProperty;
return
base.ShouldMap(member) && isPropertyToMap;
}
Another way is to use an attribute.
public class MyEntity
{
[NotMapped]
public bool A => true;
}
public class AutomappingConfiguration : DefaultAutomappingConfiguration
{
public override bool ShouldMap(Member member)
{
if (member.MemberInfo.GetCustomAttributes(typeof(NotMappedAttribute), true).Length > 0)
{
return false;
}
return base.ShouldMap(member);
}
}

Categories