Using WCF to Communicate Interface and Customer Class - c#

I have a simple WCF service which I wish to use to send data from client to server, I am unsure of the best way to serialize the data.
My apologies if this is a duplicate, but I think that my use of Interfaces and a customer class means that this is not such a simple case.
I have a simple class structure...
public interface IFoo
{
IBar MyBar{ get; }
String SomeInfo{ get; }
}
public interface IBar
{
String SomeMoreInfo{ get; }
}
public class Foo : IFoo
{
private IBar _MyBar;
private String _SomeInfo;
public String MyBar
{
get { return _MyBar; }
private set { _MyBar = value; }
}
public String SomeInfo
{
get { return _SomeInfo; }
private set { _SomeInfo= value; }
}
}
public class Bar : IBar
{
private String _SomeMoreInfo;
public String SomeMoreInfo
{
get { return _SomeMoreInfo; }
private set { _SomeMoreInfo= value; }
}
}
I have a simple WCF service to send this data...
[ServiceContract]
public interface IFooBarService
{
[OperationContract]
bool SendFooBar(IFoo request);
}
public class FooBarService : IFooBarService
{
public bool SendFooBar(IFoo request)
{
throw NotImplementedException();
}
}
My question is, what is the best way to send this data from client to server? Should I be using attributes or a DataContractResolver or is my class design flawed for WCF communication?

This link may help: http://blogs.msdn.com/b/domgreen/archive/2009/04/13/wcf-using-interfaces-in-method-signatures.aspx
ServiceKnownType and KnownType might be the friends you are looking for: (I have not tested this out completely, so take it with a grain of salt)
public interface IFoo
{
IBar MyBar { get; }
String SomeInfo { get; }
}
public interface IBar
{
String SomeMoreInfo { get; }
}
[DataContract(Name = "Foo")]
[KnownType(typeof(IFoo))]
public class Foo : IFoo
{
private IBar _MyBar;
private String _SomeInfo;
[DataMember(Name = "MyBar")]
public IBar MyBar
{
get { return _MyBar; }
private set { _MyBar = value; }
}
[DataMember(Name = "SomeInfo")]
public String SomeInfo
{
get { return _SomeInfo; }
private set { _SomeInfo = value; }
}
}
[DataContract(Name = "Bar")]
[KnownType(typeof(IBar))]
public class Bar : IBar
{
private String _SomeMoreInfo;
[DataMember(Name = "SomeMoreInfo")]
public String SomeMoreInfo
{
get { return _SomeMoreInfo; }
private set { _SomeMoreInfo = value; }
}
}
[ServiceContract]
public interface IFooBarService
{
[OperationContract]
[ServiceKnownType(typeof(Foo))]
[ServiceKnownType(typeof(Bar))]
bool SendFooBar(IFoo request);
}

Generally the input parameters of an operation is the data from client to server, and the return data is the data from server to client.
For complex types, you need to define Data Contracts.
When you create a new WCF project through Visual Studio, you get a set of skeleton codes with Service Contracts and Data Contracts. And you will see you should use objects of DataContract classes rather than interfaces to pass data, and there are no explicit codes of doing serialization, since this is done by run time.
Unless you had studied WCF in depth and have some edge and complex cases, you should not need to use DataContractResolver in common business applications.
There are a lot WCF tutorials from the Internet, for example, http://www.codeproject.com/Articles/627240/WCF-for-the-Real-World-Not-Hello-World

Related

C# satisfy members of two interfaces with one property

Issue origin: I have a generic component to display data. The data may come from different data models. To unify the access inside the component I created one interface IOne that gets implemented by all classes. In order to abstract the data access layer from the application I'm using interfaces for each data model. So each data display model implements the IOne interface and additionally one of the data model interfaces.
The interfaces:
public interface IOne
{
public int idNameOne { get; set; }
}
public interface DataModelOne
{
public int anotherNameForId{ get; set; }
}
In my class I want both members to be satisfied by one single property. My current solution is as follows:
public class Implementation : IOne, DataModelOne
{
private int _id;
public idNameOne { get { return _id; } set { _id = value; } }
public anotherIdName { get { return _id; } set { _id = value; } }
}
Is there any way to declare that one property satisfies both members? What would be a clean solution for this?
No, there's no other way than what you are doing. I'd however clean up the code (and do proper casing), by removing the backing field (and use one auto-property) and only have the other one reference the first... something like:
public class Implementation : IOne, IDataModelOne
{
public int IdNameOne { get; set }
public int AnotherIdName { get => IdNameOne; set => IdNameOne = value; }
}
(notice I've used the proper casing for the properties... should be the same casing on the interfaces too... also named IDataModelOne correctly, with an I prefix)
To avoid having both on the public API, you should usually use "explicit interface implementation" for this, for example:
public class Implementation : IOne, DataModelOne
{
public int idNameOne { get; set; }
int DataModelOne.anotherNameForId
{
get => idNameOne;
set => idNameOne = value;
}
}
or
public class Implementation : IOne, DataModelOne
{
public int Id { get; set; }
int IOne.idNameOne
{
get => Id;
set => Id = value;
}
int DataModelOne.anotherNameForId
{
get => Id;
set => Id = value;
}
}
If I really had to do this I would make the idNameOne property an auto property with anotherIdName's getter and setter referring to that property.
public class Implementation : IOne, DataModelOne
{
public idNameOne { get; set; }
public anotherIdName { get { return idNameOne; } set { idNameOne = value; } }
}
It's a little bit cleaner and show the intention a little better too.

How to use class object reference in dependency implemented class

I working on Dependency injection and taking following example if I need to use Customer class object reference in service that is implementation IService class which is best way to do so, considering customer object always going to be use in service class, or and abstract class here
public class Customer
{
public int ID {get; set;}
public string Name {get; set}
public string dosomething(){}
}
public interface IService
{
customer Serve(Guid RecordId);
}
public class Service : IService
{
public void Serve()
{
Console.WriteLine("Need to create Customer Object here");
Customer obj1 = new Customer();
obj1.ID = 2;
obj1.Name = "xyz";
}
}
public class Client
{
private IService _service;
public Client(IService service)
{
this._service = service;
}
}
Keep your model a "dumb" data container (DTO) that will never need dependencies (or for that matter, an abstraction).
public class Customer
{
public int ID { get; set; }
public string Name { get; set; }
}
Rather than having Customer do something, we have a service to do something with Customer.
public interface ISomething
{
string DoSomething(Customer customer);
}
public class Something : ISomething
{
public string DoSomething(Customer customer)
{
// Use customer to do something
return "done";
}
}
Then Service can accept ISomething as an injected dependency and process the Customer accordingly.
public interface IService
{
Customer Serve(Guid RecordId);
}
public class Service : IService
{
private readonly ISomething something;
public Service(ISomething something)
{
if (something == null)
throw new ArgumentNullException(nameof(something));
this.something = something;
}
public Customer Serve(Guid RecordId)
{
// No need to inject dependencies here
Customer obj1 = new Customer();
obj1.ID = 2;
obj1.Name = "xyz";
something.DoSomething(obj1);
return obj1;
}
}
The DTO's or the data transfer objects should contain only properties. There should not be any method implementation or an abstract method declaration or anything.
There can be a constructor in the DTO to initialize the members of the object. Try to have a look at the SOLID principles once.

C# Design Pattern - Best Way to Design For Many Datasources [duplicate]

This question already has answers here:
How to avoid Dependency Injection constructor madness?
(10 answers)
Closed 7 years ago.
I currently have an ASP.Net MVC 5 app that uses 3 external datasources (calls are made to external APIs, responses are deserialized, and mapped to business POCOs).
The app currently uses SimpleInjector to inject concrete repositories for each datasource into a business logic layer for consumption.
The problem is, as more datasources are added (potentially 20-30), the constructor will be huge and injecting all these repositories seems cumbersome.
Is there a better pattern/approach to consuming all the datasources rather than using different repositories?
Would a facade or some other pattern be more appropriate?
Very generic examples:
public class MyObject(){
public IEnumerable<Cat> Cats { get; set; }
public IEnumerable<Dog> Dogs { get; set; }
public IEnumerable<Fish> Fish { get; set; }
}
public class BusinessLogic{
private readonly ISourceARepository _sourceA;
private readonly ISourceBRepository _sourceB;
private readonly ISourceCRepository _sourceC;
public BusinessLogic(ISourceARepository sourceA, ISourceBRepository sourceB, ISourceCRepository sourceC){
_sourceA = sourceA;
_sourceB = sourceB;
_sourceC = sourceC;
}
private Dog MapSourceARecordToDog(SourceARecord record){
var result = new Dog();
if(record != null){
result.Name = record.NameField;
result.Age = record.Age;
}
return result;
}
private Cat MapSourceBRecordToCat(SourceBRecord record){
var result = new Cat();
if(record != null){
result.Name = record.NameField;
result.Weight = record.WeightField;
}
return result;
}
private Fish MapSourceCRecordToFish(SourceCRecord record){
var result = new Fish();
if(record != null){
result.ID = record.IDField;
result.Name = record.NameField;
}
return result;
}
public MyObject GetResults(){
var result = new MyObject();
result.Dogs = _sourceA.GetAll().Select(MapSourceARecordToDog).ToList();
result.Cats = _sourceB.GetAll().Select(MapSourceBRecordToCat).ToList();
result.Fish = _sourceC.GetAll().Select(MapSourceCRecordToFish).ToList();
return result;
}
}
public class SourceARespository : ISourceARepository{
public IEnumerable<SourceAResult> GetAll(){
return new List<SourceAResult>();
}
}
public class SourceBRespository : ISourceBRepository{
public IEnumerable<SourceBResult> GetAll(){
return new List<SourceBResult>();
}
}
public class SourceCRespository : ISourceCRepository{
public IEnumerable<SourceCResult> GetAll(){
return new List<SourceCResult>();
}
}
Update:
This is not a duplicate of the constructor madness question, because in this scenario, a class needs many different datasources, but still has single responsibility. Hence, it warrants its own explanation and answer.
You should only be injecting one repository per entity into a consumer that depends on it. You may also choose to adapt the repository with a business class intermediary.
UPDATE:
Based on the information provided in the question and the problem statement, here is one possible solution. Define your core infrastructure like this:
public abstract class Entity<TEntity, TDomainObject, TIRepository>
where TEntity : Entity<TEntity, TDomainObject, TIRepository>
where TDomainObject : Entity<TEntity, TDomainObject, TIRepository>.BaseDomainObject, new()
where TIRepository : Entity<TEntity, TDomainObject, TIRepository>.IBaseRepository
{
public class BaseDomainObject {}
public interface IBaseRepository
{
IEnumerable<TDomainObject> GetAll();
IEnumerable<T> GetAllMapped<T>(Func<TDomainObject, T> mapper);
}
public class BaseRepository : IBaseRepository
{
public IEnumerable<TDomainObject> GetAll()
{
return new List<TDomainObject>();
}
public IEnumerable<T> GetAllMapped<T>(Func<TDomainObject, T> mapper)
{
return this.GetAll().Select(mapper);
}
}
}
Define your source entities like this:
public class SourceA : Entity<SourceA, SourceA.DomainObject, SourceA.IRepository>
{
public class DomainObject : BaseDomainObject
{
public string Name;
public int Age;
}
public interface IRepository : IBaseRepository {}
public class Repository : BaseRepository, IRepository {}
}
public class SourceB : Entity<SourceB, SourceB.DomainObject, SourceB.IRepository>
{
public class DomainObject : BaseDomainObject
{
public string Name;
public decimal Weight;
}
public interface IRepository : IBaseRepository {}
public class Repository : BaseRepository, IRepository {}
}
public class SourceC : Entity<SourceC, SourceC.DomainObject, SourceC.IRepository>
{
public class DomainObject : BaseDomainObject
{
public Guid Id;
public string Name;
}
public interface IRepository : IBaseRepository {}
public class Repository : BaseRepository, IRepository {}
}
Then define an ISourceRepositoryContext interface like this and add each source repository interface here:
public interface ISourceRepositoryContext
{
SourceA.IRepository SourceARepository { get; }
SourceB.IRepository SourceBRepository { get; }
SourceC.IRepository SourceCRepository { get; }
}
Then define a default implementation for the interface:
public class DefaultSourceRepositoryContext : ISourceRepositoryContext
{
public SourceA.IRepository SourceARepository => new SourceA.Repository();
public SourceB.IRepository SourceBRepository => new SourceB.Repository();
public SourceC.IRepository SourceCRepository => new SourceC.Repository();
}
Define your result transport objects:
public class Dog
{
public string Name;
public int Age;
}
public class Cat
{
public string Name;
public decimal Weight;
}
public class Fish
{
public Guid Id;
public string Name;
}
public class MyObject
{
public IEnumerable<Cat> Cats { get; set; }
public IEnumerable<Dog> Dogs { get; set; }
public IEnumerable<Fish> Fish { get; set; }
}
Then consume the ISourceRepositoryContext in your BusinessLogic class:
public class BusinessLogic
{
protected ISourceRepositoryContext repositories;
public BusinessLogic(ISourceRepositoryContext repositories)
{
this.repositories = repositories;
}
public MyObject GetResults(string param1)
{
return new MyObject()
{
Dogs = this.repositories.SourceARepository.GetAllMapped
(domainObject=>new Dog
{
Age = domainObject.Age,
Name = domainObject.Name
}),
Cats = this.repositories.SourceBRepository.GetAllMapped
(domainObject=>new Cat
{
Name = domainObject.Name,
Weight = domainObject.Weight
}),
Fish = this.repositories.SourceCRepository.GetAllMapped
(domainObject=>new Fish
{
Id = domainObject.Id,
Name = domainObject.Name
}),
};
}
}
I've confirmed that the above compiles under C# 6.0.
I would recommend changing IRepository to IBusiness in Entity and split out the data access concerns from into an IDataAccess interface that only the IBusiness implementors receive via their constructors. And then change the ISourceRepositoryContext to ISourceEntities and change the IRepository properties in that interface to IBusiness properties instead.
The BusinessLogic class is the part that really concerns me. Are you sure this one class won't be taking on too many concerns? Is this supposed to be a UoW class?
For a more complete solution based on similar techniques, check out my answer to this other question: .NET Managing Layers Relationships

Register abstract managed classes with generic managing class and preserve one-to-many relationship

I have a couple abstract classes, and would like to make sure that the "Manager" is always registered with the "Managed" class such that they retain a two-way knowledge of the one-to-many relationship. That is, the Manager knows all of the Managed classes it has, and the Managed class knows who its Manager is (if it is registered with one). Further, I'd like the managed class to be able to call the specialization of its concrete manager without having to do a special cast. Is that possible?
I'd like something like this, but run into compilation issues:
class Program
{
static void Main(string[] args)
{
ConcreteManager manager = new ConcreteManager();
ConcreteManaged managed = new ConcreteManaged() { Name = "Test" };
manager.Add(managed);
managed.Process();
}
}
public abstract class BaseManager<ManagedType>
where ManagedType : BaseManaged
{
protected Dictionary<string, ManagedType> registered = new Dictionary<string, ManagedType>();
public void Add(ManagedType managed)
{
managed.Manager = this; // Cannot implicitly convert type 'BaseManager<ManagedType>' to 'BaseManager<BaseManaged>' (I've tried casting to no avail)
registered.Add(managed.Name, managed);
}
// Other common management tasks
}
public class ConcreteManager : BaseManager<BaseManaged>
{
//specialization stuff, e.g.
public void Refresh() { Console.WriteLine("Refresh Called"); }
}
public abstract class BaseManaged
{
public string Name { get; set; }
public BaseManager<BaseManaged> Manager { get; set; }
}
public class ConcreteManaged : BaseManaged
{
//specialization stuff, e.g.
public void Process()
{
Manager.Refresh();
}
}
If I change the non Program classes around a bit, as follows, I can get it to compile, but there are runtime errors (Unable to cast object of type 'TestAbstractGenerics.ConcreteManager' to type 'TestAbstractGenerics.IBaseManager`1[TestAbstractGenerics.IBaseManaged]'.):
public interface IBaseManager<ManagedType>
where ManagedType : IBaseManaged
{
void Add(ManagedType service);
}
public abstract class BaseManager<ManagedType> : IBaseManager<ManagedType>
where ManagedType : IBaseManaged
{
protected Dictionary<string, ManagedType> registered = new Dictionary<string, ManagedType>();
public void Add(ManagedType managed)
{
managed.Manager = (IBaseManager<IBaseManaged>)this;
registered.Add(managed.Name, managed);
}
// Other common management tasks
}
public class ConcreteManager : BaseManager<BaseManaged>
{
//specialization stuff, e.g.
public void Refresh() { Console.WriteLine("Refresh() called"); }
}
public interface IBaseManaged
{
string Name { get; set; }
IBaseManager<IBaseManaged> Manager { get; set; }
}
public abstract class BaseManaged : IBaseManaged
{
public string Name { get; set; }
public IBaseManager<IBaseManaged> Manager { get; set; }
}
public class ConcreteManaged : BaseManaged
{
//specialization stuff, e.g.
public void Process()
{
((ConcreteManager)Manager).Refresh();
}
}
If I change the IBaseManager<IBaseManaged> to dynamic I can remove the cast from Process() and everything works as expected, but dynamic doesn't work with intellisense, and I would like to be able to enforce the type checking (so an implementer can't accidentally set Manager to a string, for example). So what's the best practice here? Is there a good pattern to follow that allows me to preserve the one-to-many relationship?
And yes, in the above I'd have to add some logic to make sure that when BaseManaged.Manager is set that it unregisters from its current Manager, if any. I avoided that here for sake of simplicity.
Edit: this works, but still requires casting to the ConcreteManager prior to calling its non-interface methods:
class Program
{
static void Main(string[] args)
{
var manager = new ConcreteManager();
var managed = new ConcreteManaged() { Name = "Test"};
manager.Add(managed);
managed.Process();
}
}
public interface IBaseManager<ManagedType>
where ManagedType : IBaseManaged
{
void Add(ManagedType managed);
}
public abstract class BaseManager<ManagedType> : IBaseManager<ManagedType>
where ManagedType : IBaseManaged
{
protected Dictionary<string, ManagedType> registered = new Dictionary<string, ManagedType>();
public void Add(ManagedType managed)
{
managed.Manager = (IBaseManager<IBaseManaged>)this;
registered.Add(managed.Name, managed);
}
// Other common management tasks
}
public class ConcreteManager : BaseManager<IBaseManaged>
{
//specialization stuff, e.g.
public void Refresh() { Console.WriteLine("Refresh() called"); }
}
public interface IBaseManaged
{
string Name { get; set; }
IBaseManager<IBaseManaged> Manager { get; set; }
}
public abstract class BaseManaged : IBaseManaged
{
public string Name { get; set; }
public IBaseManager<IBaseManaged> Manager { get; set; }
}
public class ConcreteManaged : BaseManaged
{
//specialization stuff, e.g.
public void Process()
{
((ConcreteManager)Manager).Refresh();
}
}
I'm pretty sure the kind of cyclic relationship you want is not possible to implement perfectly type safe and without casts, because the compiler would end up getting into infinite cycles if you wanted IBaseManaged also to be generic (ie, IBaseManaged<T> where T : IBaseManager<?>), is clearly not possible to specify the constraint you need in place of ?.
You can however, create a third interface/class which can fully express this kind of circular constraint, which might provide an alternative solution.
interface IManagerAdapter<TManager, TManaged>
where TManager : IBaseManager<TManaged>
where TManaged : IBaseManaged<TManager>
IMO, if your ConcreteManaged class is going to know directly about ConcreteManager by virtue of the type cast anyway, these classes don't really provide much more than a pattern to follow for concrete types, the abstraction is kind of broken. If you need this tight coupling between the specific concrete manager and managed types anyway, I would probably make it explicity by adding the specific type in place of Managed in each class, and do away with the BaseManaged class, which doesn't help very much other than providing the Name, which is simple enough to re-implement in concrete instances.
public interface IBaseManaged<T> {
string Name { get; set; }
T Manager { get; set; }
}
public class ConcreteManaged : IBaseManaged<ConcreteManager> {
public string Name { get; set; }
public ConcreteManager Manager { get; set; }
public void Process ()
{
Manager.Refresh ();
}
}
For anything in the base types which might be more complex to implement than Name, I would opt for a Mixin like approach, where you implement that additional functionality in a separate class, and just provide a property in the interface to retreive the Mixin. For example, if all the Manager classes need to account for registering all of the Managed (as with your Add()), you obviously don't want to duplicate that functionality in each Manager - but you could simplify the approach by implementing some ManagedRegister<T> type, say (can be whatever you like), and giving the IBaseManager type a Registered field to retreive an instance.
public interface IBaseManager<T> {
ManagedRegister<T> Registered { get; set; }
}
public class ConcreteManager : IBaseManager<ConcreteManaged> {
public ManagedRegister<ConcreteManaged> Registered { get; set; }
public void Refresh () { Console.WriteLine("Refresh() called"); }
}
You still get a strongly typed Managed instances from the Register inside the Manager here.
The change from your calling code is that instead of manager.Add(managed), it becomes manager.Registered.Add(managed), and you also need to create an instance of ManagedRegister<ConcreteManaged> to pass to the ConcreteManager.. Perhaps a bit messy, and I would suggest abstracting that away into a factory, which will prevent simple mistakes like forgetting to add managed instances to the manager. We can use that circular constraint from above to implement it in a type safe way. (And if it's possible to assume every Managed/Manager has a parameterless constructor, a single implementation will work by using new() constraints. Otherwise you'll want an abstract factory and implement for each concrete type).
interface IManagerFactory<TManager, TManaged>
where TManager : IBaseManager<TManaged>
where TManaged : IBaseManaged<TManager>
{
TManager Manager { get; }
TManaged Create (string name);
}
public abstract class ManagerFactory<TManager, TManaged>
: IManagerFactory<TManager, TManaged>
where TManager : IBaseManager<TManaged>, new()
where TManaged : IBaseManaged<TManager>, new()
{
TManager manager = new TManager ();
public ManagerFactory () {
manager.Registered = new ManagedRegister<TManaged> ();
}
public TManager Manager { get { return manager; } }
public TManaged Create (string name)
{
TManaged result = new TManaged ();
result.Name = name;
manager.Registered.Add (result.Name, result);
result.Manager = manager;
return result;
}
}
public class ConcreteFactory
: ManagedFactory<ConcreteManager, ConcreteManaged> { }
Back to Main, the usage is slightly simplified here.
ConcreteFactory f = new ConcreteFactory ();
ConcreteManaged managed = f.CreateManaged ("Test");
managed.Process ();
EDIT:
Here's abstracting all of the common functionality into so called "Base classes". The key difference here is that the Base classes composed into the concrete class rather than inherited, by means of the Base property, which acts very much like the base. prefix you'd use to call base members usually.
public class BaseManager<T> {
public Dictionary<string, T> Registered { get; set; }
}
public interface IBaseManager<T> {
BaseManager<T> Base { get; set; }
}
public class ConcreteManager
: IBaseManager<ConcreteManaged> {
public BaseManager<ConcreteManaged> Base { get; set; }
public void Refresh() { Console.WriteLine("Refresh() called"); }
}
public class BaseManaged<T> {
public string Name { get; set; }
public T Manager { get; set; }
}
public interface IBaseManaged<T> {
BaseManaged<T> Base { get; set; }
}
public class ConcreteManaged
: IBaseManaged<ConcreteManager> {
public BaseManaged<ConcreteManager> Base { get; set; }
internal ConcreteManaged () { }
public void Process () {
Base.Manager.Refresh ();
}
}
interface IManagerFactory<TManager, TManaged>
where TManager : IBaseManager<TManaged>
where TManaged : IBaseManaged<TManager> {
TManager Manager { get; }
TManaged Create (string name);
}
public abstract class BaseManagerFactory<TManager, TManaged>
: IManagerFactory<TManager, TManaged>
where TManager : IBaseManager<TManaged>, new()
where TManaged : IBaseManaged<TManager>, new() {
TManager manager = new TManager();
public BaseManagerFactory() {
manager.Base = new BaseManager<TManaged>();
manager.Base.Registered = new Dictionary<string, TManaged>();
}
public TManager Manager { get { return manager; } }
public TManaged Create (string name) {
TManaged result = new TManaged();
result.Base = new BaseManaged<TManager>();
result.Base.Name = name;
manager.Base.Registered.Add (name, result);
result.Base.Manager = manager;
return result;
}
}

Implement interface and use code from existing implementation of the interface

I'm trying to implement the ITableEntity interface so that I can add [DataContract] attribute on it. But if I implement this interface myself, I'll have to give the ReadEntity and WriteEntity methods a body.
But there is a class that already implements the ITableEntity interface and gave ReadEntity and WriteEntity methods a body, which is the TableEntity.cs.
How can I make my implementation of the interface use the methods in the TableEntity class?
[Edit]
[DataContract]
public class SerializableTableEntity : ITableEntity
{
private TableEntity tableEntity;
public string ETag { get; set; }
public string PartitionKey { get; set; }
public string RowKey { get; set; }
public DateTimeOffset Timestamp { get; set; }
public SerializableTableEntity()
{
tableEntity = new TableEntity();
}
public void ReadEntity(IDictionary<string, EntityProperty> properties, Microsoft.WindowsAzure.Storage.OperationContext operationContext)
{
tableEntity.ReadEntity(properties, operationContext);
}
public IDictionary<string, EntityProperty> WriteEntity(Microsoft.WindowsAzure.Storage.OperationContext operationContext)
{
return tableEntity.WriteEntity(operationContext);
}
}
The reason that every property in your stored table is blank is because WriteEntity and ReadEntity use the blank object to store and write the data.
You're delegating serialization of your object to 'tableEntity' but none of your properties are there.
Suggestion: you will need to implement all of your SerializableTableEntity's properties inside a class that derives from TableEntity, contain a variable of that type inside the SerializableTableEntity entity, and delegate every member's property get/set from SerializableTableEntity to this new object.
Does this make sense?
EDIT: Code sample as requested (you're not going to enjoy it though)
[DataContract]
public class SerializableTableEntity : ITableEntity
{
private CustomEntity tableEntity;
public string ETag {
{
get
{
return tableEntity.ETag;
}
set
{
tableEntity.Etag = value;
}
}
public string PartitionKey
{
get
{
return tableEntity.PartitionKey;
}
set
{
tableEntity.PartitionKey = value;
}
}
public string RowKey
{
get
{
return tableEntity.RowKey;
}
set
{
tableEntity.RowKey = value;
}
}
public DateTimeOffset Timestamp
{
get
{
return tableEntity.Timestamp;
}
set
{
tableEntity.Timestamp = value;
}
}
public string PropertyOne
{
get
{
return tableEntity.PropertyOne;
}
set
{
tableEntity.PropertyOne = value;
}
}
public SerializableTableEntity()
{
tableEntity = new CustomEntity();
}
public void ReadEntity(IDictionary<string, EntityProperty> properties, Microsoft.WindowsAzure.Storage.OperationContext operationContext)
{
tableEntity.ReadEntity(properties, operationContext);
}
public IDictionary<string, EntityProperty> WriteEntity(Microsoft.WindowsAzure.Storage.OperationContext operationContext)
{
return tableEntity.WriteEntity(operationContext);
}
}
public class CustomEntity : TableEntity
{
public string PropertyOne { get; set; }
}
I ended up creating exact copy of these classes and made them Serializable. But being able to do some complex queries seems to be a challenge as well. So we moved to SQL Database.
Either delegate the "uninteresting" methods (a more realistic example is here):
class YourClass : Interface {
public void ReadEntity()
{
delegateTo.ReadEntity();
}
TableEntity delegateTo = new TableEntity();
}
or just throw an exception inside them (like NotImplementedException) - the latter will only work for you if those methods are not called.
You can create a class that contains the implementation of the TableEntity class, but also adds the functionality that you want. This is similar to the Decorator Pattern.
[Attributes...]
public class MyTableEntity : ITableEntity {
private TableEntity decoratedTableEntity;
public void ReadEntity(args...) {
decoratedTableEntity.ReadEntity(args...);
}
}
To make the solution more generic, change decoratedTableEntity to be an ITableEntity.

Categories