I have a data structure something like this:
public class HighLevelConversionData
{
public int customerID {get;set;}
public string customerName {get;set;}
public decimal amountSpent {get;set;}
}
This data will be accessed by a third party and a GWT front end, meaning I'll be using web services to move the data around. The customer is also of a different localisation than the dev team, so I'm wanting to send status messages as a wrapper for the returned data items, like so:
public class HighLevelConversionDataWrapper
{
public int StatusCode {get;set;}
public string StatusMessage {get;set;}
public List<HighLevelConversionData> {get;set;}
}
However I'd rather have an interface for these methods to inherit from, to ensure we're always sending the statuscode & message in the same way. But my understanding of how generics work in an interface seems to be failing me. I believe it should be something like:
public Interface IServiceWrapper
{
public int StatusCode {get;set}
public string StatusMessage {get;set;}
public List<T> ReturnedData {get;set;}
}
But I've come unstuck here.
Something like this?
public class ConcreteWrapper : IServiceWrapper<HighLevelConversionData>
{
public int StatusCode {get;set;}
public string StatusMessage { get; set; }
public List<HighLevelConversionData> ReturnedData { get; set;}
}
public class HighLevelConversionData
{
public int customerID {get;set;}
public string customerName {get;set;}
public decimal amountSpent {get;set;}
}
public interface IServiceWrapper<T>
{
int StatusCode { get; set; }
string StatusMessage { get; set; }
List<T> ReturnedData { get; set;}
}
If the interface has generic type parameters, the interface itself must be generic, so you'll need to do:
public interface IServiceWrapper<T>
{
public int StatusCode {get;set}
public string StatusMessage {get;set;}
public List<T> ReturnedData {get;set;}
}
and then specify the type parameters in the code like this:
public class HighLevelConversionDataServiceWrapper
: IServiceWrapper<HighLevelConversionData>
{
public List<HighLevelConversionData> ReturnedData {get;set;}
}
Related
I have a command
public class UpdateEntityCommand: IRequest<bool>
{
public int Id { get; set; }
public IEnumerable<OtherEntityDto> Instruments{ get; set; }
}
I need to update many entities in one request. Can I do something like this or there are a better way?
public class UpdateEntitiesCommand: IRequest<bool>
{
public IEnumerable<UpdateEntityCommand> Commands { get; set; }
}
Supposing your OtherEntityDto is something like this:
class OtherEntityDto
{
public Guid Id {get;set;}
public string Name {get;set;}
}
How I would do it is to have a command such as:
public class UpdateInstrumentsCommand: IRequest<bool>
{
public IEnumerable<OtherEntityDto> UpdatedInstrumemnts {get;set}
}
and then, in the command handler I will match the persisted entities with what's in the UpdatedInstrumemnts based on the Id property and update their name accordingly. I hope this makes sense to you
I have a complex type entity
public class ComplexEntity : ComplexObject
{
private int _ID;
private string _Name;
private int _ParentID;
[Key]
[DataMember]
public int ID { get;set;}
[DataMember]
public string Name {get;set;}
[DataMember]
public int ParentID {get;set;}
}
and another one
[DataContract]
public class ComplexEntitiesList : ComplexObject
{
[DataMember]
[Include]
[Association("CEntities_CEntity","ID","ParentID")]
public List<CompelxEntity> List {get;set;}
[Key]
[DataMember]
public int ID {get;set;}
public int LKEntitiesList()
{
List = new List<LKEntity>;
}
and a method:
[Invoke]
public ComplexEntitiesList GetPS()
{
return new ComplexEntitiesList() { List = /*..some logic*/});
}
On the server side everything's perfect however the list comes empty at the client side
Any clues?
}
I think the Include will not work wit Invoke-Operations. Take a look at this question on silverlight.net and see Colin Blairs answer. Your method GetPs() should return a normal collection (aka. List) containing your complex objects.
[Invoke]
public IEnumerable<ComplexEntity> GetPS() {
return new List<ComplexEntity>() { /*..some logic*/});
}
I'm going boarder line crazy, I have been working with this for over a day and still have no idea why it doesn't work,
I have a MessageContract that I'm using to send out a stream, but I get the following error,
Type 'System.IO.FileStream' with data
contract name
'FileStream:http://schemas.datacontract.org/2004/07/System.IO'
is not expected. Add any types not
known statically to the list of known
types - for example, by using the
KnownTypeAttribute attribute or by
adding them to the list of known types
passed to DataContractSerializer.
[ServiceContract()]
public interface IContentService
{
[OperationContract(), FaultContract(typeof(ContentFault))]
PublishItemResponse PublishFile(PublishFileRequest request);
}
[MessageContract()]
public class PublishFileRequest
{
[MessageHeader()]
public FileInventoryItem Item {get;set;}
[MessageHeader()]
public Request Request {get;set;}
[MessageBodyMember()]
public Stream FileContent {get;set;}
}
[MessageContract()]
public class Request
{
[MessageHeader()]
public Guid AuthorizationToken { get; set; }
[MessageHeader()]
public string CoreVersion { get; set; }
[MessageHeader()]
public string Password { get; set; }
[MessageHeader()]
public DateTime RequestTime { get; set; }
[MessageHeader()]
public string ComponentVersion { get; set; }
[MessageHeader()]
public string UserName { get; set; }
}
[MessageContract()]
[Serializable()]
public class FileInventoryItem : InventoryItemBase
{
public Stream FileContent { get; set;}
}
[MessageContract()]
[KnownType(typeof(FileInventoryItem))]
[KnownType(typeof(FolderInventoryItem))]
[Serializable()]
public abstract class InventoryItemBase
{
public List<string> Errors {get;set;}
public List<string> Warnings {get;set;}
[MessageHeader()]
public StagingAction Action {get;set;}
[MessageHeader()]
public string ContentXml {get;set;}
[MessageHeader()]
public int ItemId {get;set;}
[MessageHeader()]
public ItemType ItemType { {get;set;}
[MessageHeader()]
public string Name {get;set;}
[MessageHeader()]
public int ParentId {get;set;}
[MessageHeader()]
public Guid ParentUniqueId {get;set;}
[MessageHeader()]
public Guid UniqueId {get;set;}
[MessageHeader()]
public Guid Version {get;set;}
}
Any help is greatly appropriated,
WCF requires the types that are serialized to exactly match the types that are declared in the contract. You can get around that by adding the KnownType attribute to indicate that you know a particular sub type is going to be used (in this case you would add it to the PublishFileRequest class).
However, while that will eliminate the first error, your code will still not work, since FileStreams are not serializable.
The FileStream object points to the filesystem, which cannot be accessed from another computer.
Use a MemoryStream instead to transfer the data. You can use Stream.CopyTo(memoryStream) to copy the data to the MemoryStream object.
Is it possible to use generic support with single table inheritance, and still be able to FindAll of the base class?
As a bonus question, will I be able to use ActiveRecordLinqBase<> as well? I do love those queries.
More detail:
Say I have the following classes defined:
public interface ICompany
{
int ID { get; set; }
string Name { get; set; }
}
[ActiveRecord("companies",
DiscriminatorColumn="type",
DiscriminatorType="String",
DiscriminatorValue="NA")]
public abstract class Company<T> : ActiveRecordBase<T>, ICompany
{
[PrimaryKey]
private int Id { get; set; }
[Property]
public String Name { get; set; }
}
[ActiveRecord(DiscriminatorValue="firm")]
public class Firm : Company<Firm>
{
[Property]
public string Description { get; set; }
}
[ActiveRecord(DiscriminatorValue="client")]
public class Client : Company<Client>
{
[Property]
public int ChargeRate { get; set; }
}
This works fine for most cases. I can do things like:
var x = Client.FindAll();
But sometimes I want all of the companies. If I was not using generics I could do:
var x = (Company[]) FindAll(Company);
Client a = (Client)x[0];
Firm b = (Firm)x[1];
Is there a way to write a FindAll that returns an array of ICompany's that can then be typecast into their respective types?
Something like:
var x = (ICompany[]) FindAll(Company<ICompany>);
Client a = (Client)x[0];
Or maybe I am going about implementing the generic support all wrong?
How about this:
[ActiveRecord("companies",
DiscriminatorColumn="type",
DiscriminatorType="String",
DiscriminatorValue="NA")]
public abstract class Company : ActiveRecordBase<Company>, ICompany {
[PrimaryKey]
private virtual int Id { get; set; }
[Property]
public virtual String Name { get; set; }
}
[ActiveRecord(DiscriminatorValue="firm")]
public class Firm : Company {
[Property]
public virtual string Description { get; set; }
}
[ActiveRecord(DiscriminatorValue="client")]
public class Client : Company {
[Property]
public virtual int ChargeRate { get; set; }
}
var allClients = ActiveRecordMediator<Client>.FindAll();
var allCompanies = ActiveRecordMediator<Company>.FindAll(); // Gets all Companies (Firms and Clients). Same as Company.FindAll();
Note that you can't just downcast your Companies as Clients or Firms, you need to use proper polymorphism or a visitor. See this for an explanation.
How can i make the following class as general as possible (for maximum reuse) without creating too many classes of the same type, albeit with one extra property.
I want to avoid writing 3 slightly different versions of the same class
1# Class with No SubContent
public class Content
{
public string PageName { get; set; }
}
2# Class with Subcontent
public class Content
{
public string PageName { get; set; }
public IList<Content> SubContent {get; set;} //same as class
}
3# Class with sub content of another type
public class Content
{
public string PageName { get; set; }
public IList<DetailContent> SubContent {get; set;} //Note the different def
}
Of course i can create a generic class, but i find this confusing for consumers. It is inferring that the class is of Type T, when in fact its the Property that requires the type
public class Content<T>
{
public string PageName { get; set; }
public IList<T> SubContent {get; set;} //Note the different def
}
Generic Properties are not supported. So are there any patterns or suggestion on how i can handle this problem?
Perhaps you can have a look at the Composite Design Pattern
whats wrong with:
public class Content<T>
{
public string PageName { get; set; }
public IList<T> SubContent { get; set; } //Note the different def
}
?
it works you know...
What about
public class Content
{
public string PageName { get; set; }
}
public class ContentWithSubContent<T> : Content
{
public IList<T> SubContent { get; set; }
}
and if you want to be able to access SubContent not knowing the actual type, you could use
public class Content
{
public string PageName { get; set; }
}
public interface IContentWithSubContent
{
IEnumerable SubContent { get; }
}
public class ContentWithSubContent<T> : Content, IContentWithSubContent
{
public IList<T> SubContent { get; set; }
IEnumerable IContentWithSubContent SubContent
{
get { return this.SubContent; }
}
}
that way you can access the SubContent property bypassing generics if you need to, by using IContentsWithSubContent rather than Content.
Why not make an interface for the content classes:
public interface IContent {
public function GetContent()
}
and then you can use
List<IContent> in your content class?
you could even make the interface generic