Get concrete property that implements type - c#

Given the following classes
public Foo
{
public Foo() {
this.Bar = new Bar();
}
public IBar Bar{ get; set;}
}
public Bar : IBar
{
// implemented properties
}
How can I get the concrete implementation of the property Bar on Foo using reflection?
instance.GetType().GetProperty("Bar").PropertyType
Yields the interface only.

If you are trying to get type that implements IBar you should get it's value and take the type:
var type = instance.GetType().GetProperty("Bar").GetValue(instance,null).GetType()

Related

Moq abstract class Property is NULL when cast as interface

I've got some weird behaviour in Moq 4.2. When I make a mock of an abstract class which implements an interface which defines properties, I can access the properties just fine, as long as the instance is the original type. If I cast that instance to the underlying interface, the properties return default values.
See below for an example. Anyone have a solution to this?
In the example below, doing foo.As<IFoo>() does not help.
public interface IFoo { string Thingy { get; } }
public abstract class Foo : IFoo
{
public Foo() { Thingy = "Howdy"; }
public string Thingy { get; }
}
public class Test
{
public void DoIt()
{
var foo = new Mock<Foo>();
Console.WriteLine(foo.Object.Thingy); // prints "Howdy"
Console.WriteLine((foo.Object as IFoo).Thingy); // prints nothing
}
}
Mock - generates a proxy of some object with its own implementation.
proxyImpl1 : IFoo { string Thingy => default }
call Thingy return proxied property
proxyImpl : Foo {nothing, since the parent object does not contain virtual methods} call Thingy return parent non-overrided property.
POCO works the same way in EF

Is there any way an interface can cause different behavior?

Say I have the following code:
class Foo: IFoo {
public string fooProp { get; set; }
}
interface IFoo {
string fooProp {get; set; }
}
Is it at all possible for there to be different behavior between:
Foo x = new Foo();
someMethod(x);
and:
IFoo x = new Foo();
someMethod(x);
?
I think it may differ. If somebody's used bad style of programming, i.e.:
public void someMethod(IFoo f)
{
if (f is Foo)
{
Foo f1 = (Foo)f;
//Do smth with unique Foo members
}
//Do anything with IFoo members
}
Yes, there is a difference if someMethod has different overloads for IFoo and Foo.
public void someMethod(Foo f)
{
// Overload 1
}
public void someMethod(IFoo f)
{
// Overload 2
}
Foo x = new Foo();
someMethod(x); // Matches overload 1
IFoo x = new Foo();
someMethod(x); // Matches overload 2
(I'm no expert) but in your first scenario, you would get access to everything in Class Foo. In the second scenario, you would only be able to access the IFoo members. So if Foo has additional methods (that aren't part of the interface), you will be able to access them in your first scenario but not the second.
I believe using the interface name instead of the class name is just another way to encapsulate data and only provide access to the interface members. For instance you could have Foo and Bar which both implements IFoo. You could add both of them to, say, a List.
There would never be any difference.
Remember, an interface is a contract. By deriving Foo from IFoo, you are implementing that contract.
In both cases, because Foo is an IFoo and adheres to the contract, the behaviour will always be the same.
Of course, how Foo implements that contract is anybodies guess. But the contract is adhered too by the signature of the interface.
If you have two interfaces and there is a common method name in each of them then the implementing class can implement the same method differently. The it depends how the method is called - via interface or not and via which interface.
See here for a similar question:
Inheritance from multiple interfaces with the same method name
Different bahavior can be, but inside someMethod.
Say you have
class Foo: IFoo {
public fooProp { get; set; }
}
interface IFoo {
fooProp {get; set; }
myCustomProp {get;set}
}
if you have
public void someMethod(Foo _foo){
_foo.myCustomProp; //CAN DO THIS, AS YOUR TYPE IS _FOO_
}
Which will not be possible to do in case when the parameter of the method is defined like.
public void someMethod(IFoo _foo){
_foo.myCustomProp; //NO SUCH METHOD INFO
}
unless you don't cast. So the difference is that decaring IFoo, to decalre generic access parameter, but get less "potential" in terms of data access, but get a huge potential in abstraction over types in your architecture.
So the difference will be only in regard of architecture and program workflow.
You could have an explicitly implemented interface in Foo.
class Foo: IFoo {
private string _fooprop;
private string _ifooprop;
public string fooProp
{
get {return "IFoo";}
set {_fooprop=value;}
}
string IFoo.fooProp
{
get {return "Foo";}
set {_ifooprop=value;}
}
}
interface IFoo {
string fooProp {get; set; }
}
with this, you will have:
IFoo foo1=new Foo();
Foo foo2=new Foo();
Console.WriteLine(foo1.fooProp); // Foo
Console.WriteLine(foo2.fooProp); // iFoo
It's possible if you explicitly implement IFoo:
public class Foo : IFoo
{
public string Prop
{
get { return "Hello Foo"; }
}
string IFoo.Prop
{
get { return "Hello IFoo"; }
}
}
public static void SomeMethod<T>(T foo) where T : IFoo
{
var prop = typeof(T).GetProperty("Prop");
Console.WriteLine(prop.GetValue(foo));
}

How can I resolve circular dependencies in Funq IoC?

I have two classes which I need to reference each other.
class Foo
{
public Foo(IBar bar) {}
}
class Bar
{
public Bar(IFoo foo) {}
}
When I do:
container.RegisterAutoWiredAs<Foo, IFoo>();
container.RegisterAutoWiredAs<Bar, IBar>();
and when I try to resolve either interface I get a circular dependency graph which results in an infinite loop. Is there an easy way to solve this in Funq or do you know of a workaround?
You can always (and in all containers, I'd say) rely on Lazy as a dependency instead, and that would yield the desired result. In Funq:
public Bar(Lazy<IFoo> foo) ...
public Foo(Lazy<IBar> bar) ...
container.Register<IBar>(c => new Bar(c.LazyResolve<IFoo>());
container.Register<IFoo>(c => new Foo(c.LazyResolve<IBar>());
The answer to your question is no, there is no easy way. Given the code above, it is impossible to construct either class without Funq, so there's no reason to expect Func to be able to do it.
var foo = new Foo(/* what do I pass here? */);
var bar = new Bar(foo);
Of course, if you had another implementation of either IFoo or IBar without the dependency, or you refactored, it might be possible.
In general, the answer to the question "how do I break up circular references when doing Dependency Injection" is: "use property injection".
class Foo
{
public Foo() {}
// Break the dependency cycle by promoting IBar to a property.
public IBar Bar { get; set; }
}
class Bar
{
public Bar(IFoo foo) {}
}
With Funq I think this would be the way to register this dependency.
container.Register<IBar>(c =>
{
var foo = new Foo();
var bar = new Bar(foo);
foo.Bar = bar;
return bar;
});
Furthermore, I agree with Tim Rogers' comment. When you have a circular dependency, there is probably a problem in your design, and you should take a look at it. This is not always wrong, but often is. However, the code you show is very abstract, and there is no way for us to give any feedback on that.
This works for me:
using Funq;
using NUnit.Framework;
namespace FunqIoCyclicReferenceTest
{
[TestFixture]
public class FunqIoCCyclicReferenceTest
{
[Test]
public void Please_Work()
{
var container = new Container();
container.Register<IBar>(c => new Bar());
container.Register<IFoo>(c => new Foo(c.Resolve<IBar>()));
var foo = container.Resolve<IFoo>();
Assert.IsNotNull(foo);
}
}
public class Foo : IFoo
{
public Foo(IBar bar)
{
bar.Foo = this;
Bar = bar;
}
public IBar Bar { get; set; }
}
public interface IBar
{
IFoo Foo { get; set; }
}
public interface IFoo
{
IBar Bar { get; set; }
}
public class Bar : IBar
{
public IFoo Foo { get; set; }
}
}
EDIT
Same idea but without side-effects in constructor:
// interfaces
public interface IBar
{
IFoo Foo { get; set; }
}
public interface IFoo
{
IBar Bar { get; set; }
}
// implementations
public class Foo : IFoo
{
public IBar Bar { get; set; }
}
public class Bar : IBar
{
public IFoo Foo { get; set; }
}
// usage
container.Register<IBar>(c => new Bar());
container.Register<IFoo>(c =>
{
var bar = c.Resolve<IBar>();
var foo = new Foo();
bar.Foo = foo;
foo.Bar = bar;
});
p.s. but I do agree with Tim Rogers - circular reference is a problem to solve.
After registering your types in the container, make the container available as a static variable:
public static class ContainerHolder
{
public static Container Container {get;set;}
}
public class Foo : IFoo
{
private IBar _bar;
public Foo(IBar bar)
{
_bar = bar;
}
}
public class Bar : IBar
{
private IFoo _foo
{
get { return ContainerHolder.Container.Resolve<IFoo>(); }
}
public Bar()
{
}
}
I had a similar scenario and the dependency between the two classes made me realize they should actually be combined into a single class.

Two way reference with interfaces and generics

I've got a class with generics which uses another class, which in return needs to know what instance of the initial class "owns" it - which causes problems ;) Let me give an example:
public interface IFoo<T>
{
}
public interface IBar
{
IFoo<IBar> Foo { get; set; }
}
public class Foo<T> : IFoo<T> where T : IBar, new()
{
private readonly T _bar;
public Foo()
{
_bar = new T {Foo = this};
}
}
class Bar : IBar
{
public IFoo<IBar> Foo { get; set; }
}
This doesn't work as Foo = this doesn't work - even if I try to cast this to IFoo (compiles but fails at run time). I've tried to tweak the code various ways, but I've not found an implementation that works...
Hopefully you see what I'm trying to do, and perhaps you even see how I can achieve this ;-)
You can solve this with a combination of an explicit cast in the constructor, along with c#4.0 support for covariance on generic parameters.
First, you need to insert a cast in the Foo<T> constructor:
_bar = new T {Foo = (IFoo<IBar>)this};
Just doing that isn't sufficient, though. Your constraint that T : new() means that T needs to be a concrete class. As such, IFoo<T> will never be exactly IFoo<IBar>. However, if you specify that the generic parameter T for IBar<T> is covariant, then the cast from IFoo<Bar> to IFoo<IBar> will become legal:
public interface IFoo<out T>
The out keyword specifies that the parameter is covariant (which essentially means "this parameter will only be output by methods, never input.")
This MSDN article offers more details on covariance and contravariance.
Would declaring the T type parameter of IFoo as covariant solve your problem?
This code should allow you to do what you are trying:
public interface IFoo<out T> {
}
public interface IBar {
IFoo<IBar> Foo { get; set; }
}
public class Foo<T> : IFoo<T> where T : IBar, new() {
private readonly T _bar;
public Foo() {
_bar = new T { Foo = (IFoo<IBar>)this };
}
}
class Bar : IBar {
public IFoo<IBar> Foo { get; set; }
}
public static class Program {
public static void Main(params string[] args) {
Bar b = new Bar();
Foo<Bar> f = new Foo<Bar>();
}
}

Casting a non-generic type to a generic one

I've got this class:
class Foo {
public string Name { get; set; }
}
And this class
class Foo<T> : Foo {
public T Data { get; set; }
}
Here's what I want to do:
public Foo<T> GetSome() {
Foo foo = GetFoo();
Foo<T> foot = (Foo<T>)foo;
foot.Data = GetData<T>();
return foot;
}
What's the easiest way to convert Foo to Foo<T>? I can't cast directly InvalidCastException) and I don't want to copy each property manually (in my actual use case, there's more than one property) if I don't have to. Is a user-defined type conversion the way to go?
You can create an explicit conversion from Foo within Foo<T>.
class Program
{
static void Main()
{
Foo foo = new Foo();
foo.Name = "Blah";
Foo<int> newfoo = (Foo<int>)foo;
Console.WriteLine(newfoo.Name);
Console.Read();
}
}
class Foo
{
public string Name { get; set; }
public object Data { get; set; }
}
class Foo<T>
{
public string Name { get; set; }
public T Data { get; set; }
public static explicit operator Foo<T>(Foo foo)
{
Foo<T> newfoo = new Foo<T>();
newfoo.Name = foo.Name;
return newfoo;
}
}
Edit: This only works without inheritance. It appears you are not able to do a user-defined conversion from a base to a derived class. See comments from Mads Torgersen here http://social.msdn.microsoft.com/forums/en-US/csharplanguage/thread/14cf27cf-b185-43d6-90db-734d2ca3c8d4/ :
We have taken the liberty of
predefining conversions (casts)
between base classes and derived
classes, and to make the semantics of
the language predictable we don't
allow you to mess with it.
It looks like you may be stuck with defining a method to turn a Foo into a Foo<T>. That, or drop the inheritance. Neither solution sounds particularly ideal.
If you are getting an InvalidCastException, the Foo type returned by GetFoo() is not Foo<T>. You will need to either pass T or typeof(T) to that function so it can return an instance of Foo<T>.
Use copy constructors. Foo implements:
class Foo {
Foo(Foo copy) { ... }
}
while Foo shall be constructed using the following:
class Bar<T> : Foo {
Bar(Foo copy) : base(copy) { ... }
}
...Yes. You need to copy member by member, and this should be done in "copy constructor".

Categories

Resources