C# dapper map to interface - c#

Can i use C# dapper to do something like this:
IFoo bar = _dbConnection.Query<IFoo>("My query there");
Now I can't do it, due to not impelemented default parameterless constructor.
Is there some trick to honor gods of SOLID (especially spirits of Liskov Substitution Principle) or should i leave it as it is and map my data not to IFoo but to Foo?
I'm really worrying about respecting these SOLID stuff, but still don't know where i should do it, so looking for an advice for this concrete situation.

You need a concrete implementation of your class to instantiate. Internally, it has to do a create a new object. You can't create a new instance of an interface:
var foo = new IFoo(); // This won't build!
You can still cast your result to an interface, but you need a concrete type to build from the database.
IEnumerable<IFoo> foo = _dbConnection.Query<Foo>("My query there");

One way to organise repository is to use private class objects for querying, but expose results as public interfaces.
Pulbic Model:
namespace MyProject.Foo.Model
{
public interface IFoo
{
string Property1 { get; set; }
string Property2 { get; set; }
}
public interface IFooRepository
{
IEnumerbale<IFoo> GetFoos();
}
}
Query implementation with private class:
namespace MyProject.Foo.Repositories
{
public class FooRepository: IFooRepository
{
private class Foo: IFoo
{
public string Property1 { get; set; }
public string Property2 { get; set; }
}
public IEnumerbale<IFoo> GetFoos()
{
IEnumerable<IFoo> foo = _dbConnection.Query<Foo>("My query there");
return foo;
}
}
}

Related

Is this a valid use of the new keyword in my interface? [duplicate]

Is it advisable to use the "new" keyword in a derived interface to provide a more-derived return value for a property or method having the same name?
Say I have an interface IDocument:
public interface IDocument
{
IParagraphs Paragraphs { get; }
IRevisions Revisions { get; }
IStyles Styles { get; }
}
And a derived one IRtfDocument.
public interface IRtfDocument: IDocument
{
string Rtf { get; }
...
}
I also have more-derived interfaces for IParagraphs, IRevisions and IStyles: IRtfParagraphs, IRtfRevisions, IRtfStyles. A number of RTF-specific needs drove their creation.
When I access the paragraphs of an RTF document, I'd like to avoid casting them to IRtfParagraphs. Same for revisions and styles. It would also be nice to avoid having both "IRtfParagraphs" and "IParagraphs". So what I'd like to do is this:
public interface IRtfDocument : IDocument
{
new IRtfParagraphs Paragraphs { get; }
new IRtfRevisions Revisions { get; }
new IRtfStyles Styles { get; }
string Rtf { get; }
}
Is this considered good practice? It seems to fit in this situation, but I wanted to run it by you C# veterans.
Update: So I actually went ahead and tried using "new" as described in my interfaces. My RtfDocument class ended up needing both an IDocument.Styles property and an IRtfDocument.Styles property. While I could just have the IDocument.Styles property return the value of IRtfDocument.Styles, that doesn't feel quite right as I'm implementing two properties.
It seems the compiler doesn't account for the fact that IRtfStyles derives from IStyles, so it insists I have both. It would be nice if the Liskov Substitution Principle let me just implement IRtfDocument.Styles in the RtfDocument class.
The easier solution would probably just be to have a generic interface:
public interface IFooBox<T>
where T : IFoo
{
T Foo { get; }
}
You can then have an IFooBox<IFoo> for your basic objects, or an IFooBox<IEnhancedFoo> for the enhanced version.
This type of definition will force implementers of IEnhancedFooBox to explicitly implement IFoo.Foo separately from the implementation of IEnhancedFooBox.Foo. Since this work gets tedious, I tend to reserve this for cases where a generic interface extends a non-generic interface.
For example, consider the following interfaces.
interface IFutureValue {
object Result { get; }
}
interface IFutureValue<T> : IFutureValue {
new T Result { get; }
}
It is possible to implement a general handler for all "future values" by working with IFutureValue, where code working with future values of a specific type can work with IFutureValue<T>.
To answer the question,
Is this considered good practice?
The use of new is frowned upon, in general. However, as with all frowning in programming, it is a matter of judgement. If you have found a use for new that makes sense in your context, and you've ruled out other avenues like #Servy's example, then rock the new. Be prepared to defend your decision though.
There is big potential problem with your use of the new modifier. Suppose we use your interfaces:
public interface IFoo
{
string Name { get; set; }
}
public interface IEnhancedFoo : IFoo
{
int BarCount { get; set; }
}
public interface IFooBox
{
IFoo Foo { get; set; }
}
public interface IEnhancedFooBox : IFooBox
{
new IEnhancedFoo Foo { get; set; }
}
Build out our classes:
public class EnhancedFooBox : IEnhancedFooBox
{
public IEnhancedFoo Foo { get; set; }
IFoo IFooBox.Foo { get; set; }
}
public class FooBase : IFoo
{
public string Name { get; set; }
}
public class EnhancedFoo : IEnhancedFoo
{
public int BarCount { get; set; }
public string Name { get; set; }
}
Build some methods that take interfaces...
static void Test1(IFooBox myBlah)
{
myBlah.Foo = new FooBase();
myBlah.Foo.Name = "FooBase";
}
static void Test2(IEnhancedFooBox myBlah)
{
myBlah.Foo = new EnhancedFoo();
myBlah.Foo.Name = "EnhancedFoo";
}
And then use this logic:
static void Main(string[] args)
{
var myBlah = new EnhancedFooBox();
Test2(myBlah); //first assign name to EnhancedFoo
Test1(myBlah); //second assign name to FooBase
Console.Write(myBlah.Foo.Name);
Console.ReadKey();
}
What is the expected output? Should it be FooBase or EnhancedFoo?
EnhancedFoo
Programmers unaware the property has been modified to new, will not get the expected output. This is solved using generics.

Entity Framework 6: Using interface as navigation properties possible?

is there any way to use interfaces as navigation properties in EF6?
I've found related topics for EF4 or earlier where it didn't seem to be possible; generally, inheritance seems to have improved a lot since then, but I haven't found a way to make this specific problem work yet.
Example:
public interface IPerson
{
string name { get; set; }
}
public class Man : IPerson { /* ... */ }
public class Woman : IPerson { /* ... */ }
public interface ICar
{
IPerson driver { get; set; }
}
public class Car : ICar
{
public virtual IPerson driver { get; set; } // This won't map
}
Is this possible in any way? If not, what'd be an advisable way to do this?
Because currently I don't see any way for an interface to have a set-able property whose type is some other interface (the IPerson property of ICar, for example), which kind of strikes me as a very serious design limitation?!
Okay, for those possibly facing the same issue in the future. After more testing around, this is how I'm doing it now.
public interface IPerson
{
string name { get; set; }
}
public abstract class APerson : IPerson
{
public string name { get; set; }
}
public class Man : APerson { /* ... */ }
public class Woman : APerson { /* ... */ }
public interface ICar
{
IPerson driver { get; set; }
}
public class Car : ICar
{
// This maps to the database
public virtual APerson driver { get; set; }
// And this implements the interface
ICar.driver
{
get
{
return (IPerson)driver;
}
set
{
if(!(value is APerson))
throw new InvalidCastException("driver must inherit from APerson");
driver = (APerson)value;
}
}
}
This gets a bit more tricky when having one-to-many / many-to-many relations, for that case I've written a class that inherits from Collection<Interface type>, but also implements ICollection<Abstract base type>, and again throws an exception when someone tries adding/setting any object that doesn't inherit from the abstract base class. It's basically a Collection<IPerson> that's guaranteed to only contain objects inheriting that inherit APerson, if you will.
This solution is definitely not ideal, because it just throws an exception if somebody tries assigning a value to driver that does not inherit from APerson, so no compile-time safety here.
But it's the best solution I could think of so far, if you really want to keep your interfaces separate and self-contained.

Requiring interface implementations to have a static Parse method

I've got a minimal interface, and will be dealing with a collection of objects whose classes implement this interface. The collection (along with its associated functionality) doesn't care about any of the details of these objects beyond their name, the ability to convert them to XML, and the ability to parse them from XML.
Future implementations of the interface will do a lot more with the elements of the collection, and will obviously implement their own Parse and ToXml methods (which will be used by the collection to parse these items appropriately when encountered).
Unfortunately, I am unable to list a static Parse method in the interface (I've read these three questions). It doesn't make sense to me to have a Parse method require an instance. Is there any way to require that all implementations of the interface have a static Parse method?
public interface IFoo
{
string Name { get; }
string ToXml();
static IFoo Parse(string xml); // Not allowed - any alternatives?
}
You can't do that. And static methods aren't polymorphic anyway, so it wouldn't make too much sense.
What you want here is some kind of factory pattern.
Assuming Parse takes a string and turns it into a fully-populated object, how about a Hydrate method instead, like:
interface IFoo {
string Name { get; set; }
int Age { get; set; }
void Hydrate(string xml);
}
class Foo : IFoo {
public string Name { get; set; }
public int Age { get; set; }
public void Hydrate(string xml) {
var xmlReader = ...etc...;
Name = xmlReader.Read(...whatever...);
...etc...;
Age = xmlReader.Read(...whatever...);
}
}
void Main() {
IFoo f = new Foo();
f.Hydrate(someXml);
}
Or Fluent it up a bit:
public IFoo Hydrate(string xml) {
// do the same stuff
return this;
}
void Main() {
IFoo f = new Foo().Hydrate(someXml);
}
The only alternative that comes to my mind is to use an abstract class instead of an interface here. However you won't be able to override static method's behaviour in child classes anyway.
You can achieve somewhat similar behaviour using Factory pattern and requiring classes implementing IFoo to have a reference to that Factory (which can be injected in them via constructor injection):
public interface IFoo
{
string Name { get; }
string ToXml();
IFooFactory FooFactory { get; }
}
public interface IFooFactory
{
IFoo Parse(string xml);
}
I would extract all serialization-related methods into a different interface. Please consider the following example:
public interface IFoo
{
string Name { get; }
IFooSerializer GetSerializer(string format);
}
public enum FooSerializerFormat { Xml, Json };
public interface IFooSerializer
{
string Serialize(IFoo foo);
IFoo Deserialize(string xml);
}
public class Foo : IFoo
{
public string Name { get; }
public IFooSerializer GetSerializer(FooSerializerFormat format)
{
case FooSerializerFormat.Xml:
return new FooXmlSerializer();
case FooSerializerFormat.Json:
return new FooJsonSerializer();
}
}
public class FooXmlSerializer : IFooSerializer { /* Code omitted. */ }
public class FooJsonSerializer : IFooSerializer { /* Code omitted. */ }
Maybe this way?
public interface IFoo
{
string Name { get; }
string ToXml();
IFoo Parse(string xml);
}
public abstract class AFoo : IFoo
{
public string Name { get; set; }
public string ToXml() { };
public IFoo Parse(string xml) { return AFoo.StaticParse(xml); };
public static IFoo StaticParse(string xml) { }; // implement one here
}
Even if the above could be a solution I would encourage you to use the abstact factory and/or template method instead. See Template Method Pattern instead. Another Option might be the usage of an Extension method if you wan't to share it among several implementations.
Broadly speaking, I have been known (on occasion) to use Extension methods for stuff like this:
public interface IFoo
{
string Name {get;}
string ToXml();
}
public class Foo : IFoo
{
public Foo(string name)
{
Name = name;
}
public string Name {get; private set;}
public string ToXml()
{
return "<derp/>";
}
}
So that's the instance stuff, let's handle the "static" bit:
public static class FooExts
{
public static IFoo Parse(this string xml)
{
return new Foo("derp");
}
}
And a test:
void Main()
{
var aFoo = "some xml".Parse();
Console.WriteLine(aFoo.ToXml());
}
As #Jim mentions, there is the case where you don't want a Foo back, in which case you might use something like:
public static T Parse<T>(
this string xml,
Func<string, IFoo> useMeUseMe = null)
where T:IFoo
{
if(useMeUseMe == null)
useMeUseMe = (x => new Foo(x));
return (T)useMeUseMe("derp");
}
Alas, we must now tell the method what we want when we deviate from the "norm":
var aFoo = "some xml".Parse<Foo>();
Console.WriteLine(aFoo.ToXml());
var aBar = "some xml".Parse<Bar>(s => new Bar(s));
Console.WriteLine(aBar.ToXml());

Can I deserialize to a read-only property of an interface in protobuf-net?

I've got an interface and an implementation, both with [ProtoContract]. There is one property, which is read-only on the interface. When I try to deserialize a property declared as the interface, Protobuf gives me this error:
System.InvalidOperationException: Cannot apply changes to property IFoo.Id
Here's the code I'm testing with:
public void Main()
{
using (var ms = new MemoryStream())
{
var x = new HasFoo {TheFoo = new Foo(1)};
Serializer.Serialize(ms, x);
ms.Position = 0;
var clone = Serializer.Deserialize<HasFoo>(ms);
Assert.AreEqual(1, clone.TheFoo.Id);
}
}
[ProtoContract, ProtoInclude(100, typeof(Foo))]
public interface IFoo
{
[ProtoMember(1)]
long Id { get; }
}
[ProtoContract]
public class Foo : IFoo
{
[ProtoMember(1)]
public long Id { get; private set; }
public Foo() { }
public Foo(long id)
{
Id = id;
}
}
[ProtoContract]
public class HasFoo
{
[ProtoMember(1)]
public IFoo TheFoo { get; set; }
}
I'd rather not declare a setter on the interface, and I'd like to keep the TheFoo property declared as IFoo if at all possible. Is there any way that can be made to work? I'm using protobuf-net v2.
No. When binding to an interface, it binds to the interface, so it can't exploit any private setters (etc) that would be available when binding to the concrete type. The only way you could do that would be to advertise the members of Foo for serialization instead of IFoo.
Note: in non-interface scenarios it will have access to the members, or even the direct field of desired.

Can you use the C# new keyword to expand properties on an interface?

I understand how the "new" keyword can hide methods in a derived class. However, what implications does it have for classes that implement interfaces that use the keyword?
Consider this example, where I decide to expand an interface by making its properties read/write.
public interface IReadOnly {
string Id {
get;
}
}
public interface ICanReadAndWrite : IReadOnly {
new string Id {
get;
set;
}
}
Then you are able to do things like this:
public IReadOnly SomeMethod() {
// return an instance of ICanReadAndWrite
}
Is this bad design? Will it cause issues for my classes that implement ICanReadAndWrite?
Edit: Here is a contrived example of why I might want to do something like this:
Say I have a factory class that returns an IShoppingCartItemReadWrite. I can then have a service layer that manipulates prices on it, changes stuff, etc. Then, I can pass these objects as IShoppingCartItemReadOnly to some kind of presentation layer that won't change them. (Yes, I know it technically can change them-- this is a design question, not security, etc.)
It's not a particularly bad idea. You should be aware that the implementor can (if it implicitly implements the interface, then a single read/write property could satisfy both interfaces) provide two distinct implementations:
class Test : ICanReadAndWrite {
public string Id {
get { return "100"; }
set { }
}
string IReadOnly.Id {
get { return "10"; }
}
}
Test t = new Test();
Console.WriteLine(t.Id); // prints 100
Console.WriteLine(((IReadOnly)t).Id); // prints 10
By the way, in general, the new inheritance modifier does nothing except to tell the compiler to shut up and don't throw out a "you're hiding that member" warning. Omitting it will have no effect in the compiled code.
You should not implement the ICanReadWrite based on IReadOnly, but instead make them separate.
ie. like this:
public interface IReadOnly
{
string Id
{
get;
}
}
public interface ICanReadAndWrite
{
string Id
{
get;
set;
}
}
Here's a class using them:
public class SomeObject : IReadOnly, ICanReadWrite
{
public string Id
{
get;
set;
}
}
Note that the same property in the class can support both interfaces.
Note that as per the comment, the only way to get a robust solution would be to also have a wrapper object.
In other words, this is not good:
public class SomeObject : IReadOnly, ICanReadWrite
{
public string Id
{
get;
set;
}
public IReadOnly AsReadOnly()
{
return this;
}
}
as the caller can just do this:
ICanReadWrite rw = obj.AsReadOnly() as ICanReadWrite;
rw.Id = "123";
To get a robust solution, you need a wrapper object, like this:
public class SomeObject : IReadOnly, ICanReadWrite
{
public string Id
{
get;
set;
}
public IReadOnly AsReadOnly()
{
return new ReadOnly(this);
}
}
public class ReadOnly : IReadOnly
{
private IReadOnly _WrappedObject;
public ReadOnly(IReadOnly wrappedObject)
{
_WrappedObject = wrappedObject;
}
public string Id
{
get { return _WrappedObject.Id; }
}
}
This will work, and be robust, right up until the point where the caller uses reflection.
This is perfectly legal and the implications for your class that implements the ICanReadAndWrite interface would simply be that when it is treated as an IReadOnly it can only read, but when treated as ICanReadAndWrite it would be able to do both.
I'm not sure if that compiles or not, but is not an advisable pattern to follow. With the ability to do explicit interface implementation, you could theoretically provide two entirely different implementations for the IReadOnly and ICanReadAndWrite versiond of the Id property. Consider altering the ICanReadAndWrite interface by adding a setter method for the property rather than replacing the property.
You can do it but I am not sure what you hope to accomplish by doing it.
public IReadOnly SomeMethod() {
// return an instance of ICanReadAndWrite
}
This method will return a reference to an IReadOnly which means that it doesn't matter that you have returned an ICanReadAndWrite. Wouldn't this approach be better?
public interface IReadOnly
{
String GetId();
}
public interface ICanReadAndWrite : IReadOnly
{
String SetId();
}

Categories