I'm writing an implementation of IWsdlExportExtension and I've collected a list of PropertyInfo instances that need their corresponding XSD declarations to be modified. In order to do this, I need to determine their XML namespace.
I understand that looking at the DataMemberAttribute is not enough. Is there a built in method in the WCF libraries that can provide that information? Otherwise, would the algorithm look like to determine this?
I believe what you want is get an instance of the ContractDescription class. This class has a namespace property.
You can get an instance of this class using one of the GetContract methods. They have a Type parameter. So In your case, you could use this kind of call:
string myNamespace = ContractDescription.GetContract(
typeof(IMyService),
myPropertyInfo.DeclaringType).Namespace;
NOTE: you will also need the contract type (represented in this sample by typeof(IMyService))
Related
I have an API exposed via Spring Data Rest which, for the most part, is read-only but which allows for updating of some properties via PATCH requests.
Is there any (I'm supposing Jackson) configuration at a global level that would essentially make an entity read only unless specific properties were annotated in some way.
I am familiar with the#JsonProperty(access = Access.READ_ONLY) Jackson annotation however would like to avoid having to annotate all read-only properties.
For example, given the class below only the field explicitly annotated would be writable. All other fields would be readable by default:
public class Thing{
private String fieldOne;
#JsonProperty(access = Access.READ_WRITE)
private String fieldTwo;
private String fieldThree;
// a lot of other properties
}
Failing any global configuration, is there anything that can be applied at the class level?
I am not aware of any way to globally set all attributes in a class to read only. Since version 2.6+ of FaserXML you can use the following annotation to at least defined the set of properties you would ignore and only allow for serialization. The following annotation would be used at the class level:
#JsonIgnoreProperties(value={ "fieldOne", "fieldThree"}, allowGetters=true)
It is not exactly what you are looking for, but arguably makes coding a little easier.
I have noticed that some of my serialized objects stored in Redis have problems deserializing.
This typically occurs when I make changes to the object class being stored in Redis.
I want to understand the problem so that I can have a clear design for a solution.
My question is, what causes deserialization problems?
Would a removal of a public/private property cause a problem?
Adding new properties, perhaps?
Would a adding a new function to the class create problems? How about more constructors?
In my serialized object, I have a property Map, what if I change (updated some properties, added functions, etc) myObject, would it cause a deserialization problem?
what causes deserialization problems?
I would like to give you bit of background before answering your question,
The serialization runtime associates with each serializable class a version number, called a serialVersionUID, which is used during deserialization to verify that the sender and receiver of a serialized object have loaded classes for that object that are compatible with respect to serialization. If the receiver has loaded a class for the object that has a different serialVersionUID than that of the corresponding sender's class, then deserialization will result in an InvalidClassException.
If a serializable class does not explicitly declare a serialVersionUID, then the serialization runtime will calculate a default serialVersionUID value for that class based on various aspects of the class, It uses the following information of the class to compute SerialVersionUID,
The class name.
The class modifiers written as a 32-bit integer.
The name of each interface sorted by name.
For each field of the class sorted by field name (except private static and private transient fields:
The name of the field.
The modifiers of the field written as a 32-bit integer.
The descriptor of the field.
if a class initializer exists, write out the following:
The name of the method, .
The modifier of the method, java.lang.reflect.Modifier.STATIC, written as a 32-bit integer.
The descriptor of the method, ()V.
For each non-private constructor sorted by method name and signature:
The name of the method, .
The modifiers of the method written as a 32-bit integer.
The descriptor of the method.
For each non-private method sorted by method name and signature:
The name of the method.
The modifiers of the method written as a 32-bit integer.
The descriptor of the method.
So, to answer your question,
Would a removal of a public/private property cause a problem? Adding new properties, perhaps? Would a adding a new function to the class create problems? How about more constructors?
Yes, all these additions/removal by default will cause the problem.
But one way to overcome this is to explicitly define the SerialVersionUID, this will tell the serialization system that i know the class will evolve (or evolved) over the time and don't throw an error. So the de-serialization system reads only those fields that are present in both the side and assigns the value. Newly added fields on the de-serialization side will get the default values. If some fields are deleted on the de-serialization side, the algorithm just reads and skips.
Following is the way one can declare the SerialVersionUID,
private static final long serialVersionUID = 3487495895819393L;
I want to be able to define in my web.config the type of connexion my object will use to get data (variable) (from an xml or from a databases).
I though about using a Strategie Pattern, but I'm somewhat stuck by the need to write somewhere the name of the class, which I do not want.
Any suggestions?
Additionnal info
I have the interface IContext.
It's implemented in ContextXML and ContextDB.
I have the class Context which has a IContext member (called _context).
The Context class reads (through ContextConfiguration) app.config.
I want _context to be able to be a ContextXML or a ContextDB... or a ContextJSon or any other new class that would implements IContext.
Have you thought about creating a ContextManager class and employing "configuration by convention"?
What I would do, is add a member getName to your IContext interface - this just returns a nice human-readable string for each implementation - as simple as "ContextXML" for your ContextXML class.
When your ContextManager (probably a Singleton, BTW) starts up, it scans a known directory for IContext implementations, instantiating them by reflection (or some other mechanism, I'm not familiar with VB.Net but I'm sure there's a way), and placing them in a collection.
Now when you are building up Context objects, you can ask your ContextManager for a suitable IContext - either explicitly [e.g. getIContextByName("ContextDB")] or with a simpler method that just returns whatever has been configured by some other mechanism - i.e. a suite of methods something like this:
getPossibleIContextImplementationNames()
setCurrentIContextImplementation({name})
getCurrentIContext()
Just as an aside, are you stuck with that naming? Because having a Context object that uses an IContext seems a little unusual. If your IContext implementations are actually used to retrieve data from somewhere, why not call the interface IDAO or IDataAccessor?
I've been battling with AS3 for a little while now, and I'm working on a simple application using only actionscript and the FlashDevelop/flex-compiler combo. I've hit a bit of a wall in my fledgling OOP understanding, and I'm wondering whether someone might be able to point me in the right direction. I have genuinely read several books, and spent many hours reading online tutorials etc, but something's just not clicking!
What's baffling me is this: When something is declared 'public', according to what I read, it is therefore available anywhere in the application (and should therfore be used with care!) However, when I try to use public properties and methods in my program, they most definitely are not available anywhere other than from the class/object that instantiated them.
This leads me to conclude that even if objects (of different class) are instantiated from the same (say 'main') class, they are not able to communicate with each other at all, even through public members.
If so, then fair enough, but I've honestly not seen this explained properly anywhere. More to the point, how do different objects communicate with other then? and what does Public actually mean then, if it only works through a direct composition hierarchy? If one has to write applications based only on communication from composer class to it's own objects (and presumably use events for, er, everything else?) - isn't this incredibly restrictive?
I'm sure this is basic OOP stuff, so my apologies in advance!
Any quick tips or links would be massively appreciated.
There are different topics you are covering in your question. Let me clarify:
What does the modifier public mean?
How can instances of the same class communicate to each other?
--
1.
In OOP you organize your code with objects. An object needs to be instantiated to provide its functionality. The place where you instantiate the object can be considered as the "context". In Flash the context might be the first frame, in a pure AS3 movie, it might be the main class, in Flex it could be the main mxml file. In fact, the context is always an object, too. Class modifier of your object public class MyClass tells your context whether it is allowed to instantiate the object or not. If set to internal, the context must live in the same directory as the class of the object. Otherwise it is not allowed to create a new object of the class. Private or protected are not valid class modifiers. Public class ... means that any context may create an object of that class. Next: Not only instantiation is controlled by these modifiers but also the visibility of a type. If set to internal, you cannot use an expression like var obj : InternalType in a context that does not live in the same directory as Internal type.
What about methods and properties? Even if your context is allowed to access a type, certain properties and methods might be restricted internal/protected/private var/method and you perhaps are not able to invoke them.
Why we're having such restrictions? Answer is simple: Differnent developers may develop different parts of the same software. These parts should communicate only over defined interfaces. These interfaces should be as small as possible. The developer therefore declares as much code as possible to be hidden from outside and only the necessary types and properties publicly available.
Don't mix up with modifiers and global properties. The modifier only tells you if a context is allowed to see a type or method. The global variable is available throughout the code. So even if a class is declared to be public, instances of that class do not know each other by default. You can let them know by:
storing the instances in global variables
providing setter such as set obj1(obj1 : OBJ1) : void where each object needs to store the reference in an instance variable
passing the object as method arguments: doSomething(obj1 : OBJ1)
Hope this helps you to more understand OOP. I am happy to answer your follow up questions.
Jens
#Jens answer (disclaimer: I skimmed) appears to be completely correct.
However, I'm not sure it answers your question very directly, so I'll add a bit here.
A public property is a property of that class instance that is available for other objects to use(function: call, variable: access, etc). However, to use them you must have a reference (like a very basic pointer, if that helps?) to that object instance. The object that instantiates (creates, new ...) that object can take that reference by assigning it to a variable of that class type.
// Reference is now stored in 's'
public ExampleClass s = new ExampleClass();
If you'd like to, you do have the option of making a static property, which is available just by knowing the class name. That property will be shared by all instances of that class, and any external class can refer to it (assuming it's public static) by referring to the class name.
A public property is referred to by the reference you stored.
//public property access
s.foo
s.bar(var)
A static property is referred to by the class name.
//static property access
ExampleClass.foo
ExampleClass.bar(var)
Once you've created the instance, and stored the reference, to an object, you can pass it around as you'd like. The below object of type OtherExampleClass would receive the reference to 's' in its constructor, and would have to store it in a local variable of its own to keep the reference.
public OtherExampleClass s2 = new OtherExampleClass(s);
I am fairly new to WCF and just have a question on how to correctly get MessageContract inheritance working. A simplified version of my setup is as follows - a "base" message type, and then another "test" message which inherits from it.
[MessageContract]
public abstract class BaseMessage
{ }
[MessageContract]
public class TestMessage : BaseMessage
{ }
I then have an asynchronous OperationContract on a ServiceContract defined as:
[OperationContract(AsyncPattern = true)]
IAsyncResult BeginFindRequest(BaseMessage request, AsyncCallback callback, object asyncState);
The problem that I am getting is when calling the BeginFindRequest method, and passing in a TestMessage instance for the request parameter, the WCF framework is deserialising the TestMessage instance to BaseMessage on the service/server side. As this is defined as an abstract class, it results in the following error:
"The message cannot be deserialized
into MessageContract type BaseMessage
since it does not have a default
(parameterless) constructor."
From the limited information that I can find on MessageContract inheritance, it seems that it should just work.
So my question is - what am I missing in order to get this to work; or should I perhaps rather define a seperate OperationContract on the ServiceContract specifically for that type - the downside being that I could end up with many additional OperationContracts?
In the end I found this blog post which hit the nail on the head -
Unfortunately the way that contracts
are expressed in WCF makes is very
easy to forget what their purpose is:
to define the messages send to the
operation and being sent back from the
operation. In reality you have to
think “how would I express this data
in XML?”. XML doesn’t support
inheritance so whatever you put in the
contract is going to have to have some
way of mapping to XML. The data
contracts used to define the messages
are simply a .NET typed convenience
for generating the XML for the data
you want to pass – if you view them
any other way you are destined for a
world of pain. So think about the data
you want to pass, not how it may
happen to be represented in your
business layer and design your
DataContracts accordingly.
http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,a3775eb1-b441-43ad-b9f1-e4aaba404235.aspx
So I will be refactoring to provide an additional method with an explicit contract type. This will also allow me to clean up the service implementation by removing all the type checking.
Thanks for the assistance.
OK, first question is: why are you really using Message contracts? Do you really have a need for that??
Typically, message contracts are only ever used when you need to tightly control the layout of your SOAP message, e.g. to satisfy a legacy system you need to call which requires specific headers and such.
A "normal" WCF call should hardly ever need to use a message contract.
You define your service calls (the methods on your service) using [ServiceContract], and the data structures being passed around as [DataContract]. If you have a DataContract, you have more options as to how to deal with inheritance / polymorphism in your service (more than with the message contract construct).
Marc
Is that possible to change BaseMessage so that it is concrete class with parameterless constructor?
The error message tells that there is no way to initialize the object of type BaseMessage because it is abstract.
The error simply wants you to have a default empty contructor that it can use. However, I agree with marc_s; in the projects I've worked on I've rarely used message contract, the only case I can remember was as part of a file transfer service where file chunks were passed in messasges.
Try decorating your [ServiceContract] with the KnownType attribute. Since TestMessage is not 'visible' from a public operation, this helps the plumbing know how to treat it when it sees it.
If this should allow the [DataContract] to be serialized as a TestMessage your still likely to need to handle multiple messages differently via 'is a' or some other casting.
Well I had declared this default (parameterless) constructor for sure, but that was not still working fine for me, for me the issue was, the access modifier was protected while it should be public:
public constructor() { }
^^^^