This is my Scenario:
public class Foo
{
private readonly List<Lazy<IAnimal>> _animals;
public Foo(List<Lazy<IAnimal>> animals )
{
_animals = animals;
}
public void Bark()
{
//Line: *
var dog = _animals.First(p => p.GetType() == typeof (Dog)).Value;
}
Public void Mio()
{
//Line: *
var dog = _animals.First(p => p.GetType() == typeof (Cat)).Value;
}
}
public class Dog:IAnimal
{
}
public class Cat:IAnimal
{
}
public interface IAnimal
{
}
Questions:
Here The list of Animals are Lazily injected into the class Foo.
I want to do something like Line * with Ninject. As you may know the problem is that before resolving a class, GetType() returns Null. So how can I resolve just one of the Items in the list whenever I want?
Can Ninject do such a thing at all or I have to change my DI Container?
This is a chicken and the egg problem: you don't know the type unless you get the value. You can only solve this by adding extra information to the list that is known before hand.
This is a good fit for Lazy<T, TMetadata> which is part of the System.ComponentModel.Composition assembly:
public class Foo
{
private readonly List<Lazy<IAnimal, Type>> _animals;
public Foo(List<Lazy<IAnimal, Type>> animals)
{
_animals = animals;
}
public void Bark()
{
var dog = _animals.First(p => p.Metadata == typeof(Dog)).Value;
}
}
Update
As I said in the comments, I'm no Ninject expert, but most things can be done with a framework, even when there is no built-in support for it. This is what I think your registration would look like. I might have the Ninject syntax wrong, but it would look a bit like this:
var list = new List<Lazy<IAnimal, Type>>();
list.Add(new Lazy<IAnimal, Type>(() => kernel.Get<Dog>(), typeof(Dog)));
list.Add(new Lazy<IAnimal, Type>(() => kernel.Get<Pussy>(), typeof(Pussy)));
list.Add(new Lazy<IAnimal, Type>(() => kernel.Get<Horse>(), typeof(Horse)));
kernel.Bind<List<Lazy<IAnimal, Type>>().ToConstant(list);
You can use the OfType extension method provided in the System.Linq namespace.
var dog = _animals.OfType<Dog>().First();
Related
I'm trying to create an AutoFixture.ICustomization that loops over every type that inherits from my model base and then explicitly doesn't assign any values to properties that also derive from that model base.
Obviously, this requires some serious abuse of reflection.
So far, I've got this:
public class DiscosModelFixtureCustomizationNoLinks: ICustomization
{
public void Customize(IFixture fixture)
{
Type[] discosModelTypes = typeof(DiscosModelBase).Assembly.GetTypes().Where(t => t.IsDiscosModel() && !t.IsAbstract).ToArray();
MethodInfo customizeMethod = fixture.GetType().GetMethods().Single(m => m.Name == nameof(fixture.Customize) && m.IsGenericMethod); // Needed to resolve overload with generic
foreach (Type t in discosModelTypes)
{
MethodInfo constructedCustomizeMethod = customizeMethod.MakeGenericMethod(t);
Type customizationComposer = typeof(ICustomizationComposer<>).MakeGenericType(t);
PropertyInfo[] propsToIgnore = t.GetProperties().Where(p => p.PropertyType.IsDiscosModel()).ToArray();
foreach (PropertyInfo prop in propsToIgnore)
{
// I want to essentially do this
// For every prop that derives from DiscosModelBase
// fixture.Customize<DiscosObject>(c => c.Without(p => p.Id));
// Using my constructed method
constructedCustomizeMethod.Invoke(fixture, new [] {myExpression});
}
}
}
}
So .Customize<T>() has this signature:
void Customize<T>(Func<ICustomizationComposer<T>, ISpecimenBuilder> composerTransformation);
And ICustomizationComposer<T>.Without() has this signature:
IPostprocessComposer<T> Without<TProperty>(Expression<Func<T, TProperty>> propertyPicker);
So essentially, I need to work out how to build the equivalent of c => c.Without(p => p.Id) using reflection and my PropertyInfo.
This answer would indicated that I can manually build the expression tree, however, it's not really explained in enough detail that I'm able to apply it in this context.
First up, is this possible? Secondly, if so, how do I accomplish this missing step?
So it seems as though I was massively overcomplicating this. Following some assistance from the dev behind AutoFixture, it's been made clear that what I'm trying to accomplish can be done through the use of an Omitter.
This Omitter requires a PropertySpecification which requires an instance of IEquatable<PropertyInfo> to tell it which properties to ignore.
So putting all of that together inside a customizer gives us:
public class DiscosModelFixtureCustomizationNoLinks: ICustomization
{
public void Customize(IFixture fixture)
{
var omitter = new Omitter(new PropertySpecification(new DiscosModelPropertyComparer()));
fixture.Customizations.Add(omitter);
}
private class DiscosModelPropertyComparer : IEquatable<PropertyInfo>
{
public bool Equals(PropertyInfo other) => other.PropertyType.IsDiscosModel();
}
}
For completeness, IsDiscosModel() is:
public static class TypeExtensions
{
public static bool IsDiscosModel(this Type t) =>
t.IsAssignableTo(typeof(DiscosModelBase)) ||
t.HasElementType && t.GetElementType()!.IsAssignableTo(typeof(DiscosModelBase)) ||
t.IsCollectionType() && t.IsGenericType && t.GetGenericArguments().Single().IsAssignableTo(typeof(DiscosModelBase));
}
Extra Info
It's worth noting that, while I didn't need it, the linked discussion shows how PropertySpecifications can be combined together with and and or statements to develop complex conditions for Omitters. For instance, if we take a type comparer that matches a given base type:
public class DeclaringTypeComparer : IEquatable<PropertyInfo>
{
public DeclaringTypeComparer(Type declaringType)
{
this.DeclaringType = declaringType;
}
public Type DeclaringType { get; }
public bool Equals(PropertyInfo other)
{
return other.DeclaringType == this.DeclaringType;
}
}
This can then be combined to ignore all properties inherited from base type and one specific property of a child type.
var spec = new OrRequestSpecification(
new PropertySpecification(new DeclaringTypeComparer(typeof(BaseType))),
new AndRequestSpecification(
new PropertySpecification(
new DeclaringTypeComparer(typeof(ChildType))),
new PropertySpecification(
new PropertyTypeAndNameCriterion(
new Criterion<Type>(typeof(IReadOnlyList<int>), EqualityComparer<Type>.Default),
new Criterion<string>("Numbers", StringComparer.Ordinal)))));
var omitter = new Omitter(spec);
var fixture = new Fixture();
fixture.Customizations.Insert(0, omitter);
This is what I am trying to get
(IList<Foo>)listPropertyInfo.GetValue(item)
This is how I get Foo type
listPropertyInfo.GetValue(item).GetType().GenericTypeArguments[0]
This is what I tried but couldn't make it successfully
Convert.ChangeType(listPropertyInfo.GetValue(item), IList<listPropertyInfo.GetValue(item).GetType().GenericTypeArguments[0]>)
and also this;
((typeof(IList<>).MakeGenericType(listPropertyInfo.GetValue(item).GetType().GenericTypeArguments.Single())))(listPropertyInfo.GetValue(item))
this is method where I am trying to implement
public static void trigger(IList<T> result)
{
foreach (var item in result)
{
foreach (var listPropertyInfo in typeof(T).GetProperties().ToList().FindAll(x => x.PropertyType.Name == typeof(IList<>).Name))
{
trigger((IList<Foo>)listPropertyInfo.GetValue(item));
}
}
}
I solved like this;
IList targetList = (IList)listPropertyInfo.GetValue(item);
Type foo = targetList.GetType().GenericTypeArguments.Single();
Type unboundGenericType = typeof(READ<>);
Type boundGenericType = unboundGenericType.MakeGenericType(foo);
MethodInfo doSomethingMethod = boundGenericType.GetMethod("trigger");
object instance = Activator.CreateInstance(boundGenericType);
doSomethingMethod.Invoke(instance, new object[] { targetList, f, properties });
If you use IList notation, Foo must be defined at compile time, you can't use expression that evaluates at runtime for Foo.
After reading your comments and and the code i would argue you are trying to do it at the wrong spot.
Here an example of how you could do this
public class MyGeneric<T>
{
public static void trigger(IList<T> result)
{
// do generic stuff where
// you do not need to know T
}
}
// this class does only explicit Foo related stuff
public class MyNONEGeneric
{
public static void trigger(IList<Foo> list)
{
// do some
}
}
class Program
{
static void Main(string[] args)
{
PersistentGenericBag<Foo> magicBag = myMagic<Foo>();
// call your generic which do some general list related stuff
MyGeneric<Foo>.trigger(list);
// call your none generic which do some foo related stuff
MyNONEGeneric.trigger(list);
}
}
like you can see i did some sort of "separation of concerns" / "single responsibility principle" here.
Every thing does only "one" thing. so if you are in need to change something you will know exactly where.
Also if you are working in a Team you can tell Person A to do the MyGeneric<T> and Person B to do the MyNONEGeneric
I have this factory class which converts a Foo into a list of Bar objects. Foo is a very complex object which I flatten into a list of simple Bar objects. There are about 60 different bits of data that could be transformed from a Foo into a Bar. The following implementation works but there's definite scope for improvement here.
public class FooToBarsConverter
{
public List<Bar> Convert(Foo foo)
{
return Enum.GetValues(typeof(BarTypeEnum))
.Cast<BarTypeEnum>()
.Select(barType => CreateBar(foo, barType))
.Where(newBar => newBar != null)
.ToList();
}
public Bar CreateBar(Foo foo, BarTypeEnum barType)
{
switch (barType)
{
case BarTypeEnum.TypeA:
return CreateTypeA(foo);
case BarTypeEnum.TypeB:
return CreateTypeB(foo);
}
return null;
}
private Bar CreateTypeA(Foo foo)
{
return new Bar(...);
}
private Bar CreateTypeB(Foo foo)
{
return new Bar(...);
}
}
Ideally I'd like to avoid having to write a new case to the switch every time a new BarType is added. Perhaps a dictionary of types and delegate functions but that would still require a mapping of sorts? Is there any feature of the language that I can exploit to avoid this switch case a make the compiler choose the create create function?
Assuming you don't mind the factory methods being statics this does neaten it up a bit without needing the cruft of having to create ~60 more sub-classes to get the type system to do the work for me. I think the statics aren't needed if you make it a func with the factory as well but I've not got that far yet. The statics don't particularly bother me with it just being data transposition
private static readonly IDictionary<BarTypeEnum, Func<Foo, Bar>>
CreateLookup = new Dictionary<BarTypeEnum, Func<Foo, Bar>>
{
{ BarTypeEnum.TypeA, CreateTypeA },
{ BarTypeEnum.TypeB, CreateTypeB }
};
public Bar Create(Foo foo, BarTypeEnum barType)
{
Func<Foo, Bar> createDelegate;
CreateLookup.TryGetValue(barType, out createDelegate);
return createDelegate != null ? createDelegate(foo) : null;
}
private static Bar CreateTypeA(Foo foo) { ... }
private static Bar CreateTypeB(Foo foo) { ... }
Is there any feature of the language that I can exploit to avoid this switch case a make the compiler choose the create create function?
Yes. It's called polymorphism
Check this video: Jimmy Bogard - Crafting Wicked Domain Models on how an enum could be converted into a polimorhic class hierachy.
Basically you create an abstract class called BarTypeEnum that feels like an enum and create n derived types, one for each enum value. Then you could have this method
public abstract Bar CreateBar(Foo foo);
and override it in every subclass each returning a diferent subtype of Bar
e.g.
public override Bar CreateBar(Foo foo)
{
return CreateTypeA(foo);
}
BTW: The enumeration class he talks about is on NuGet as the NuGet package Enumeration
EDIT
I just checked and the nuget package class is not the same as the video. It is a Generic, nonpolimorphic way to implement it though
Not a huge fan of this because it's a bit hard to read, but you can define a custom attribute, mapping each enum value to its method. You'd use reflection to find and execute the appropriate method.
public class BarChooserAttribute : Attribute
{
public BarChooserAttribute(BarTypeEnum barType) { BarType = barType; }
public BarTypeEnum BarType { get; set; }
}
public static class CreateBarMethods
{
[BarChooser(BarTypeEnum.TypeA)]
public static Bar CreateTypeA(Foo foo)
{
return new Bar { Message = "A" };
}
[BarChooser(BarTypeEnum.TypeB)]
public static Bar CreateTypeB(Foo foo)
{
return new Bar { Message = "B" };
}
}
public static Bar CreateBar(Foo foo, BarTypeEnum barType)
{
var methodWrapper = typeof(CreateBarMethods).GetMethods(BindingFlags.Public | BindingFlags.Static)
.Select(m => new { Method = m, Att = (BarChooserAttribute)m.GetCustomAttributes(typeof(BarChooserAttribute), false).Single() })
.Single(x => x.Att.BarType == barType);
return (Bar)methodWrapper.Method.Invoke(null, new[] { foo });
}
To improve performance, you can map the methods into a dictionary one time and retrieve them from the dictionary each time. Additionally, you can use expression trees to compile the methods into lambda expressions, so you only have to do reflection once instead of each time you make the call. Significant performance improvements, to get significantly harder-to-read code, so it's a trade-off.
Personally I don't mind a switch in a factory method, it's readable, it's neat and doesn't sarcrafice the end goal of what a factory method is for - keeping the initialization code together.
However, that being said, I wonder if a custom attribute could tidy this up a bit for you. Going on the assumption all the CreateBarX methods create an instance of Bar initializing the specific properties from Foo.
[System.AttributeUsage(System.AttributeTargets.Field)]
public class FooConverter : System.Attribute
{
public string Parameters;
public Bar GetInstance(Foo foo)
{
var propNames = String.IsNullOrEmpty(Parameters) ? new string[] { } : Parameters.Split(',').Select(x => x.Trim());
var parameters = foo.GetType().GetProperties().Where(x => propNames.Contains(x.Name)).Select(x => x.GetValue(foo));
return (Bar)Activator.CreateInstance(typeof(Bar), parameters.ToArray());
}
}
// extension helpers
public static class EnumExt
{
public static Bar GetInstance(this BarTypeEnum value, Foo foo)
{
var converterAttr = value.GetAttribute<FooConverter>();
return converterAttr != null ? converterAttr.GetInstance(foo) : null;
}
public static T GetAttribute<T>(this System.Enum value)
{
FieldInfo fi = value.GetType().GetField(value.ToString());
var attributes = fi.GetCustomAttributes(typeof(T), false);
return attributes.Length > 0 ? (T)attributes[0] : default(T);
}
}
Which would allow you to do
public enum BarTypeEnum
{
[FooConverter] // no properties mapped
TypeA,
[FooConverter(Parameters="Prop1")] // map Prop1 from Foo to Bar
TypeB,
TypeC, // no instance
[FooConverter(Parameters="Prop1, Prop2")] // map Prop1/2 from Foo to Bar
TypeD,
TypeE // no instance
}
public List<Bar> Convert(Foo foo)
{
return Enum.GetValues(typeof(BarTypeEnum))
.Cast<BarTypeEnum>()
.Select(barType => barType.GetInstance(foo))
.Where(newBar => newBar != null)
.ToList();
}
And that's all you need!
However, there are some limitations to this approach with respect to the parameter injection, CreateInstance will only match the constructor based on a signature which matches the data type i.e.
// this will call Bar(string prop1, string prop2)
Activator.CreateInstance(typeof(Bar), new object[] { "Property1", "Property2" });
// where as this will car Bar(string prop1)
Activator.CreateInstance(typeof(Bar), new object[] { "Property2" });
The ordering is important as well
// this will call Bar(string prop1, string prop2) so Prop1 = "Property2"
Activator.CreateInstance(typeof(Bar), new object[] { "Property2", "Property1" });
However, there are ways around this - for the most part this will probably work well.
I hate 'case's and I like Generics therefore I slightly changed interface of FooToBarsConverter:
public interface IFooToBarsConverter
{
List<Bar> Convert(Foo foo);
Bar CreateBar<TBarType>(Foo foo) where TBarType : Bar;
}
There is an implementation:
public class FooToBarsConverter : IFooToBarsConverter
{
public List<Bar> Convert(Foo foo)
{
return new List<Type>
{
typeof(Bar.BarA),
typeof(Bar.BarB)
}.Select(it => CreateBar(foo, it))
.ToList();
}
public Bar CreateBar<T>(Foo foo)
where T : Bar
{
return CreateBar(foo, typeof(T));
}
private Bar CreateBar(Foo foo, Type barType)
{
return typeof(Bar).IsAssignableFrom(barType)
? (Bar)Activator.CreateInstance(barType, foo)
: null;
}
}
public class Foo
{
}
public abstract class Bar
{
private Bar(Foo foo)
{
}
public class BarA : Bar
{
public BarA(Foo foo)
: base(foo)
{
}
}
public class BarB : Bar
{
public BarB(Foo foo)
: base(foo)
{
}
}
}
... and a test that tests it:
[TestMethod]
public void TestMethod()
{
// arrange
var foo = new Foo();
var target = new FooToBarsConverter();
// act + assert
var list = target.Convert(foo);
list.Should().HaveCount(2);
list.Should().NotContainNulls();
var typeA = target.CreateBar<Bar.BarA>(foo);
typeA.Should().BeAssignableTo<Bar.BarA>();
var typeB = target.CreateBar<Bar.BarB>(foo);
typeB.Should().BeAssignableTo<Bar.BarB>();
}
Greetings everyone!
I'll try to make my problem simple: I have an enum to select which ObjType I should use (ObjTypeA and ObjTypeB both inherits from ObjType). So I created a method to extend the given enum, in order to return a new instance according to the selected property in the enum, like follows in the code. I think it works more or less like a factory design pattern. So far so good, but eventually, like in the class MyClass, I may attempt to create n instances of ObjTypeA or ObjTypeB, but I'll have to face the if statement everytime I call the GetObjTypeInstance() method. So:
Can an enum return an instance, something like: public enum EObjType { ObjTypeA = new ObjTypeA(), ObjTypeB = new ObjTypeB() }? Actually, it'd be better to append some GetInstance() method to the ObjTypeA and to the ObjTypeB options in the enum. If there's a way to do this, how can I do it? Doing this I'd avoid those if statements every while step.
Is there any other (and better) way to this this (if you understood my problem...)? How?
Thanks in advance!
Follow the example code:
public static class EObjTypeExt
{
public static ObjType GetObjTypeInstance(this EObjType ot)
{
if (ot == EObjType.ObjTypeA)
{
return new ObjTypeA();
}
else if (ot == EObjType.ObjTypeB)
{
return new ObjTypeB();
}
throw new ArgumentOutOfRangeException("unrecognized type!");
}
}
public enum EObjType { ObjTypeA, ObjTypeB }
public class MyClass
{
ObjType[] obj { get; set; }
public MyClass(EObjType otEnum, int n)
{
this.obj = new ObjType[n];
int i = 0;
while (i < n)
{
this.obj[i] = otEnum.GetObjTypeInstance();
i++;
}
}
}
You'll have to byte this apple somewhere.
Maybe replace the if/elseif chain with switch statement, they work great with enums.
Instead of using an enum, I would use a class that looks like an enum:
public class EObjType {
public static readonly EObjType ObjTypeA = new EObjType(() => (ObjType)(new ObjTypeA));
public static readonly EObjType ObjTypeB = new EObjType(() => (ObjType)(new ObjTypeB));
private readonly Func<ObjType> generator;
private EObjType(Func<ObjType> generator) {
this.generator = generator;
}
public ObjType GetInstanceOfObjType() {
return generator();
}
}
You can then use it exactly as you have been the enum.
EObjType otEnum = EObjType.ObjTypeA;
ObjType obj = otEnum.GetInstanceOfObjType();
You need to use a factory or other creational design pattern.
For instance, you could hold a dictionary from enum key to type value to get the desired class type using selected enum value. Then use reflection to create a new instance (object) of received type.
Initialize static dictionary's values using static constructor of factory class. You can enter the values manually or better yet, load possible values from a config file.
I'm not sure that I'd really advocate this approach, but you could call the enum ToString() method, treat that as your class name and use reflection to instantiate an object of that type.
One advantage of this would be that you could reflect and get the type once, then call the constructor n times in your loop.
As Danny Varod points out, a dictionary mapping your enum values to their Types (or to functions that create those types) would allow you to avoid if statements. Since enum is really just an integer underneath, an array would be more memory and time efficient, but readability is probably most important here.
You could create a factory that allows registration of functions that map to your enumeration, you could that use some sort of registration process to register your different enumerations
public class ObjectFactory
{
private readonly Dictionary<MyObjectType, Func<MyObject>> _store = new Dictionary<MyObjectType, Func<MyObject>>();
public void Register<T>(MyObjectType type) where T: MyObject, new()
{
this.Register(type, () => new T());
}
public void Register(MyObjectType type, Func<MyObject> factory)
{
_store.Add(type, factory);
}
public MyObject CreateInstance(MyObjectType type)
{
Func<MyObject> factory;
if(_store.TryGetValue(type, out factory))
{
return factory.Invoke();
}
return null;
}
}
public enum MyObjectType { A, B }
public class MyObject {}
public class MyObjectA : MyObject {}
public class MyObjectB : MyObject {}
Usage as follows
var factory = new ObjectFactory();
factory.Register<MyObjectA>(MyObjectType.A);
factory.Register<MyObjectB>(MyObjectType.B);
var a = factory.CreateInstance(MyObjectType.A);
var b = factory.CreateInstance(MyObjectType.B);
Assert.IsInstanceOf(typeof(MyObjectA), a);
Assert.IsInstanceOf(typeof(MyObjectB), b);
You could use Activator.CreateInstance.
public class ObjType {}
public class ObjTypeA : ObjType {}
public class ObjTypeB : ObjType {}
public enum EObjType { ObjTypeA, ObjTypeB }
public static class EObjTypeExt
{
public static ObjType GetObjTypeInstance( EObjType ot)
{
object o = Activator.CreateInstance(null,ot.ToString());
return (ObjType)o;
}
}
I find myself (too) often using a construct like the following:
class MyClass
{
public TypeA ObjectA;
public TypeB ObjectB;
public TypeC ObjectC;
public List<TypeD> ListOfObjectD = new List<TypeD>();
public void DoSmth()
{
return SomeConstruct(
/*...*/
new Setter<TypeA>(a => ObjectA = a), // these are the
new Setter<TypeB>(b => ObjectB = b), // things I'm trying
new Setter<TypeC>(c => ObjectC = c), // to make shorter
new Setter<TypeD>(d => ListOfObjectD.Add(d)),
/*...*/
);
}
}
class Setter<T>
{
public Action<T> Action;
public Setter(Action<T> action)
{
Action = action;
}
}
Is there any way for the Setter class to infer the type of the Action and create the standard (T obj) => Member = obj Action by only passing the Member in some way? I'm thinking of something like:
new Setter(ObjectA)
which of course is not valid syntax, but should give you an idea what I'm trying to achieve. I'm using this construct literally hundreds of time in my code, so the code
saved by this small change would be tremendous.
Edit: Added the TypeD example. The part
new Setter<TypeD>(d => ListOfObjectD.Add(d))
can be simplified to
new Setter<TypeD>(ListOfObjectD.Add)
which is awesome because it cuts from the redundant code. If only <TypeD> could also be inferred it would be perfect. I'm looking for something like this for the others.
#Lazarus - basically the purpose is to return setters, so other objects can set certain members of the class (or it can do other stuff defined in the Action) without accessing the class itself, only the Setter object. The full list of reasons is long and convoluted, but the structuring of the program works like a charm and I doubt needs changing (the example of course is simplified and doesn't really make sense as is).
Edit 2: I found a good way to simplify things for List's:
static class SetterHelper
{
public static Setter<T> GetSetter<T>(this List<T> list)
{
return new Setter<T>(list.Add);
}
}
Now I can just use this:
ListOfObjectD.GetSetter()
which works perfectly! why can't I do the same for T directly? I tried this:
static class SetterHelper
{
public static Setter<T> GetSetter<T>(this T item)
{
return new Setter<T>(t => item = t); // THIS DOESN'T SET THE PASSED MEMBER
}
}
Of course it won't work as intended because it will set item, but not the passed member. I tried adding ref as (ref this T item) but it won't compile :(... It would have been perfect.
Best I can offer you is the following syntax:
Setter.For( () => ObjectA );
using this helper class
static class Setter
{
public static Setter<T> For<T>(Expression<Func<T>> e)
{
ParameterExpression[] args = { Expression.Parameter(((e.Body as MemberExpression).Member as FieldInfo).FieldType) };
Action<T> s = Expression.Lambda<Action<T>>(Expression.Assign(e.Body, args[0]), args).Compile();
return new Setter<T>(s);
}
}