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());
Related
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;
}
}
}
I have an abstract base configuration class and two implementations:
public abstract class BaseConfiguration
{
}
public class LoginConfiguration : BaseConfiguration
{
public LoginConfiguration()
{
}
public string Name { get; set; }
public string Password { get; set; }
}
public class TestConfiguration : BaseConfiguration
{
public TestConfiguration()
{
}
}
The problem I am facing:
Every specific class type has a explicit filename it points to. This means LoginConfiguration has a filename called "login.xml" and TestConfiguration points to "test.xml".
The filename I would like to use for deserialization later on:
static void Main(string[] args)
{
LoginConfiguration login = ReadFromFile<LoginConfiguration>();
Console.ReadLine();
}
private static TConfig ReadFromFile<TConfig>() where TConfig : BaseConfiguration
{
//Something like this needs to be done here:
string filename = TConfig.GetFilename();
//Deserialize file and return object
return Deserialize<TConfig>(filename);
}
But I know that you can neither have static overides nor static abstract methods.
What I am currently doing is using the base class to instantiate a new object and read the filename from the instance, but thats very hacky.
public abstract class BaseConfiguration
{
protected BaseConfiguration(string fileName)
{
Filename = fileName;
}
public string Filename { get; private set; }
public static string GetFilename<TConfig>() where TConfig : BaseConfiguration, new()
{
return new TConfig().Filename;
}
}
//The calling method:
private static TConfig ReadFromFile<TConfig>() where TConfig : BaseConfiguration, new()
{
string filename = BaseConfiguration.GetFilename<TConfig>();
//Deserialize file and return object
return Deserialize<TConfig>(filename);
}
My question is now:
Do you have any idea, how I can design it better? Do you have a better Approach?
And wouldn't static abstract methods in C# make sense at this kind of issue?
Thanks in advance!
If you don't mind a bit of reflection, you could add an attribute to provide the file name:
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class ConfigFileAttribute : Attribute
{
...
}
[ConfigFile("login.xml")]
public class LoginConfiguration
{
...
}
Since you already have the type (TConfig), you can access the attribute using:
var configAttributes = typeof(TConfig).GetCustomAttributes(typeof(ConfigFileAttribute), false);
Of course this does mean that forgetting the attribute would make the read fail.
This is not the "best" solution, but I personally prefer the separate administration of a filename, where the class itself has no interest in it.
The reason for your weird design is because your XXXConfiguration class breaks Single Responsibility Principle, it has a property named filename, to tell the caller where its data comes from, and other properties to save the loaded data. IMO the XXXConfiguration class should only contain the data, there is no information of its data source.
abstract class BaseConfiguration
{
public string SharedConfigProperty { get; set; }
}
class LoginConfiguration : BaseConfiguration
{
public string LoginConfigProperty { get; set; }
}
class TestConfiguration : BaseConfiguration
{
public string TestConfigProperty { get; set; }
}
In your original design, LoginConfiguration can only have one data-source, it will be a nightmare if you have login-dev.xml login-qa.xml in the future. Put the load function of configurations in another class is better:
class ConfigurationFactory
{
public static TConfig FromFile<TConfig>() where TConfig : BaseConfiguration
{
//you should have a TConfig-fileName mapping
//e.g. a Dictionary<Type, string>
//Type is typeof(TConfig) and string is the filename
}
public static TConfig FromDataBase<TConfig>() where TConfig : BaseConfiguration
{
//as I said, the original design has a lot of restricts
//what if they change the storage from file to data base?
//you need to change every derived class, renaming FileName to DataBaseTableName?
}
}
Yeah I sometimes wish for the ability to specify a contract 'if you extend this class then you need to provide a static method with this signature', but unfortunately that doesn't exist.
It's not that much neater, but I would probably make a static map of the filenames like this:
public abstract class BaseConfiguration
{
static BaseConfiguration()
{
Filenames = new Dictionary<Type, string>
{
{ typeof(LoginConfiguration), "login.xml" },
{ typeof(TestConfiguration), "test.xml" },
};
}
private static Dictionary<Type, string> Filenames { get; }
public static string GetFilename<TConfig>() where TConfig : BaseConfiguration
{
return Filenames[typeof(TConfig)];
}
}
The advantages being that you have all the filenames in one place and that you don't need to allocate an instance to get the filename.
Having these two methods declared in a non-generic class, which share the same signature:
private TypeResolverResult<T> TryRetrieveFromReusable<T>(TypeResolverConfiguration<T> typeResolverConfiguration) where T : class
{
return null;
}
private TypeResolverResult<T> BuildNew<T>(TypeResolverConfiguration<T> typeResolverConfiguration) where T : class
{
return null;
}
How can I create a delegate that represents these methods' signature?
I can't seem to get it, I tried:
private Func<TypeResolverConfiguration<T>, TypeResolverResult<T>> _typeResolveFunc;
But obvious this does not work because the class is non-generic and I can't change that.
Thanks
UPDATE
This is more or less what I need:
public class Manager : ATypeResolver, IManager
{
private neeedDelegate;
public Manager(RuntimeConfiguration runtimeConfiguration, IList<RepositoryContainer> repositories)
{
if (runtimeConfiguration.WhatEver)
{
neeedDelegate = TryRetrieveFromReusable;
}
else
{
neeedDelegate = BuildNew;
}
}
public override TypeResolverResult<T> Resolve<T>() where T : class
{
//Want to avoid doing this:
if (runtimeConfiguration.WhatEver)
{
TryRetrieveFromReusable(new TypeResolverConfiguration<T>());
}
else
{
BuildNew(new TypeResolverConfiguration<T>());
}
//and have just this
neeedDelegate<T>(new TypeResolverConfiguration<T>());
}
private TypeResolverResult<T> TryRetrieveFromReusable<T>(TypeResolverConfiguration<T> typeResolverConfiguration) where T : class
{
return null;
}
private TypeResolverResult<T> BuildNew<T>(TypeResolverConfiguration<T> typeResolverConfiguration) where T : class
{
return null;
}
}
Update From what I can see, an approach like this should work, as long as ATypeResolver has a where T : class on Resolve<T>:
public class Manager : ATypeResolver, IManager
{
private bool tryRetrieveFromReusable;
public Manager(RuntimeConfiguration runtimeConfiguration, IList<RepositoryContainer> repositories)
{
this.tryRetrieveFromReusable = runtimeConfiguration.WhatEver;
}
public override TypeResolverResult<T> Resolve<T>()
{
var typeResolver = tryRetrieveFromReusable ? (TypeResolver<T>)TryRetrieveFromReusable : BuildNew;
return typeResolver(new TypeResolverConfiguration<T>());
}
}
This uses a custom delegate type (a Func like you have should work too):
public delegate TypeResolverResult<T> TypeResolver<T>(
TypeResolverConfiguration<T> typeResolverConfiguration) where T : class;
If you like, you can move the var typeResolver = ... line to its own method, to separate the logic and allow you to use it from more than just Resolve. If you did that, Resolve might be as simple as: return GetTypeResolver<T>()(new TypeResolverConfiguration<T>());.
You seem to not understand exactly how generics work. I'll give a quick overview, but read the MSDN.
When you have a generic class
public class Foo<T>
{
public T Bar {get; set;}
}
And you use it something like this
Foo<int> intFoo = new Foo<int>();
Foo<string> stringFoo = new Foo<string();
At compile time, the compiler will detect the two usages of the generic type. It will create a type of each usage. So your assembly will have types that look something like this (no not exactly, but let's play pretend so that we humans can understand).
public class FooInt
{
public int Bar { get; set; }
}
public class FooString
{
public string Bar { get; set; }
}
And it will replace all uses of Foo<int> with FooInt and Foo<string> with FooString
Now if we have a non-generic class with a generic method
public class Foo
{
public T GetBar<T>() { ..... }
}
And you use it like this
Foo foo = new Foo();
int x = foo.GetBar<int>();
string s = foo.GetBar<string();
The compiler will generate
public class Foo
{
public int GetBarInt() { ..... }
public string GetBarString() { ..... }
}
And it will replace GetBar<T> with GetBarInt and GetBar<string> with GetBarString
But fields aren't like that. If you have a class that looks like so
public class Foo
{
public T Bar;
}
You cannot do this
Foo foo = new Foo();
foo.Bar<int> = 1;
foo.Bar<string> = "test";
The compiler just doesn't understand that. I'm not an expert on the internals, but my guess is that because this points to a place in memory, the compile cannot generate the generic usages at compile time.
But the point I am trying to make is this. Generics are not some magical "I don't need to specify the type" feature. They are hints to the compile that say "I am going to do this same thing multiple times, I want you to generate the code for me."
I have an interface for a base class, and every class that inherits from the base class should have an identifying field which tells the application what kind of object it is.
I wanted to use this property in two different ways:
Without creating an instance of the object
if (someValue == TestA.Id)
return new TestA();
elseif (someValue == TestB.Id)
return new TestB();
And as a property of the interface
void DoSomething(ITest testObject)
{
SomeValue = testObject.Id;
}
Is there an easy way to define the Id field in the interface, but still have it available to use without creating an instance of the class?
Right now I am using the following code. I could add a read-only Id property to the interface which returns the const string, however I was hoping there was a simpler way that I'm just not aware of.
public interface ITest
{
}
public class TestA : ITest
{
public const string Id = "A";
}
In short - no.
In order to be able to do this, you'd need to be able to specify this as a instance property on the interface (and implement it in the instance), and as a static property on the type.
The compiler won't let you do this.
You can put it in the interface, and also have it as a static property. Something like:
interface IInterface { Id { get; } }
class Class : IInterface
{
public static Id { get { return 1; } }
public Id { get { return Class.Id; } }
}
I've faced a similar problem, Rachel, and I've always (unfortunately) resorted to having that factory code rely on reflection to get a "TypeID" public static property on each concrete type... thus making an additional aspect of the contractual interface, but not having it in the C# interface code.
You could do it this way.
public interface ITest
{
SomeValue Id{ get;}
}
public class TestA : ITest
{
public SomeValue Id
{
get {return TestA.StaicId; }
}
public static SomeValue StaticId
{
get {return "This is TestA";}
}
}
if (someValue == TestA.StaticId)
return new TestA();
How about using attributes? Here's a small example of what can be done:
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
public class IdAttribute : Attribute
{
public IdAttribute(string id)
{
this.Id = id;
}
public string Id { get; set; }
}
public interface IMyInterface
{
}
public abstract class BaseClass : IMyInterface
{
public static string GetId<T>() where T : IMyInterface
{
return ((IdAttribute)typeof(T).GetCustomAttributes(typeof(IdAttribute), true)[0]).Id;
}
}
[Id("A")]
public class ImplA : BaseClass
{
}
[Id("B")]
public class ImplB : BaseClass
{
}
internal class Program
{
private static void Main(string[] args)
{
var val1 = BaseClass.GetId<ImplA>();
var val2 = BaseClass.GetId<ImplB>();
Console.ReadKey();
}
}
I am trying to implement an IDescription Interface. Basic purpose of this interface is that I have many different classes that have a list of multilingual descriptions and I want the the basic AddDescription EditDescription and some other basic behaviours to be defined by the interface and not implemented by the classes individually that inherits the interface. I am trying to assign the behavior to the interface using extension methods.
I have some road blocks such as how do I access the descriptions collection of the entity that I am passing on to the IDescription interface (entity.Descriptions.Add)?
I am very new to generics, extension methods, anonymous types etc so please bear with me with my misunderstandings of how these are used. Will appreciate if you can help me correct the below code. I wrote it to give the idea of what I am trying to achieve, it obviously fundamental errors in it. Thanks
public class Company : IDescription<Company, CompanyDescription>
{
public IList<CompanyDescription> Desriptions { get; set; }
}
public class Location : IDescription<Location, LocationDescription>
{
public IList<LocationDescription> Desriptions { get; set; }
}
public interface IDescription<eT, dT>
{
void AddDescription(eT, string text);
void EditDescription(eT, dT, string text);
}
public static DescriptionInterfaceExtensions
{
public static void AddDescription(this IDescription<eT, dT> description, eT entity, string text)
{
dT newDescription = new dT(text);
entity.Descriptions.Add(newDescription);
}
}
Another possible rewrite that should work is to remove the Add/Edit methods from the interface and simply provide the required IList in the interface. Then, for ease of use, you can use the extension methods to make it easier.
I'm not saying this example is a great use of generics or extension methods, but it will work:
public class CompanyDescription : IDescription { public string Text { get; set; } }
public class LocationDescription : IDescription { public string Text { get; set; } }
public class Company : IHaveDescriptions<CompanyDescription>
{
public IList<CompanyDescription> Desriptions { get; set; }
}
public class Location : IHaveDescriptions<LocationDescription>
{
public IList<LocationDescription> Desriptions { get; set; }
}
public interface IDescription
{
string Text { get; set; }
}
public interface IHaveDescriptions<T>
where T : class, IDescription, new()
{
IList<T> Desriptions { get; set; }
}
public static class DescriptionInterfaceExtensions
{
public static void AddDescription<T>(this IHaveDescriptions<T> entity, string text)
where T : class, IDescription, new()
{
T newDescription = new T();
newDescription.Text = text;
entity.Desriptions.Add(newDescription);
}
public static void EditDescription<T>(this IHaveDescriptions<T> entity, T original, string text)
where T : class, IDescription, new()
{
T newDescription = new T();
newDescription.Text = text;
entity.Desriptions.Remove(original);
entity.Desriptions.Add(newDescription);
}
}
I your example it seems the contract is that objects that have a description store a list of descriptions. So, to avoid having to declare Add and Remove methods in the classes directly, you could do something like this:
Interfaces
public interface IDescription<T>
{
}
public interface IHasDescription<THasDescription, TDescription>
where THasDescription : IHasDescription<THasDescription, TDescription>
where TDescription : IDescription<THasDescription>
{
IList<TDescription> Descriptions { get; }
}
Concrete implementations
public class CompanyDescription : IDescription<Company>
{
}
public class Company : IHasDescription<Company, CompanyDescription>
{
private readonly IList<CompanyDescription> descriptions;
public IList<CompanyDescription> Descriptions
{
get { return this.descriptions; }
}
}
Extension methods
public static class DescriptionExtensions
{
public static void AddDescription<THasDescription, TDescription>(
this THasDescription subject,
TDescription description)
where THasDescription : IHasDescription<THasDescription, TDescription>
where TDescription : IDescription<THasDescription>
{
subject.Descriptions.Add(description);
}
}
But I don't think it's worth to do this just to have
mycompany.AddDescription(mydescription);
instead of
mycompany.Descriptions.Add(mydescription);
You can't add interface implementations to classes using extension methods, although that seems to be what you are trying to do.
The purpose of extension methods is to add behavior to existing types (classes or interfaces).
The problem with your code is that you declare that Company and Location should implement the IDescription interface; yet they don't. They have no AddDescription or EditDescription methods, so that's not going to work.
Why don't you instead define a concrete generic Description class and attach that class to Company and Location?