I have a requirement where based on the Class Name passed as string from a Third party application, I want to get all properties and its value and assign their values to another object having members with similar names. Now I know this can be done without any issue in a Win Form application but I want to know what all issues will be there if I use this approach in an ASP.NET application - I am not much concerned with the Performance but specifically with the Concurrency (if any possible)
I am using code something like as below:
//Just a Sample Code
Type type = Type.GetType("MyClassName");
var propValue = type.GetProperty("MyProperyName").GetValue(myObject);
Any help will be appreciated.
Concurrency Issues like Race condition etc will come into picture if you are writing or making changes to the values, here you only reading properties, which are already added to metadata of type (Type definition, property definition) tables when you compile your code.
And there is no way you can alter that definition at runtime as long as I know, so the things you are doing is thread safe as long as your type and propvalues are local to thread executing.
Related
I have the following structure:
struct someData
{
public bool check;
public string text;
}
...
someData sd = new someData(){ check = true, text = "just testing" };
Cache.Insert(cacheInd, sd, null, Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(90));
Then later on the code, I want to retrieve the data from cache, but I get an InvalidCastException:
if (Cache[cacheInd] != null)
{
someData sd = (someData)Cache[cacheInd];//Error here
If I try this:
someData sd = Cache[cacheInd] as someData;
I get:
The as operator must be used with a reference type or nullable type ('ASP._dev_pull_aspx.someData' is a non-nullable value type)
Any ideas on how to solve it?
Here's what I'm doing:
Load page (not cached yet) -> everything is fine
Reload it (cached) -> everything is fine
Change code, not related to it somewhere else in the page -> get the exception
Recycling the cache fixes it (until i change code again)
Note: thanks for MethodMan and Michael Humelsine for explanation of as failure - Why can't I use the as keyword for a struct?, but failure to perform cast is still unclear especially since it works most of the time.
It looks like you get 2 different types with type named the same as result of re-compilation of the page and hence you can't cast one to another despite very similar names/structure.
Why:
in .Net type identity includes full name and assembly identity (name) like "System.Int32 from System.dll v4.0.0.0".
changing an ASPX/CSHTML page produces new assembly with random name but does not trigger recycle of app-domain (especially in debug configuration) till some relatively high threshold of "number of dynamically compiled assemblies" is hit (don't have good link handy, search. I.e. this one talks about diff between ASPX vs. Razor )
You should be able to see complete types if you compare whole Type objects (typeof(someData) vs. Cache[cacheInd].GetType() - one of the properties would be different, i.e. Type.FullName likely candidate.
I'd expect the types to look similar to following (with difference in the name of its assembly):
{ASP._dev_pull_aspx.someData from "ASP._dev_pull_aspx._3333.dll"
{ASP._dev_pull_aspx.someData from "ASP._dev_pull_aspx._7777.dll"
To fix you should move types you care about to compiled assemblies from pages or live with the fact that sometimes types will not match and restart app-domain. Normally rebuilding project or web.config change would trigger app-domain recycle as it is part of recycle triggers along with number of recompilations of individual pages.
Notes:
changing struct someData to class someData would still reproduce the error, but you may see more detailed message instead with as types still will be different
the other common cases of such error are having copy of the same type in several assemblies/namespaces due to code sharing (as in include the same source file into multiple project) and using multiple versions of the same strongly named assembly.
Well, I just tested a struct like yours, stored it in cache and retrieved it with the cast syntax (i.e. (someData)Cache[cacheInd]).
It worked fine with no casting issues and no exceptions. What is the value of the "cacheInd" variable in your example? Can it change between the time it is used to store the item in the cache and the time it retrieves it?
Have you debugged to see what the data type is of the object/struct that IS stored in the cache?
The lack of issues I faced seem to point to something other than an issue with serializing/deserializing a struct.
Lets say my c# model updated while correspondent collection still contains old documents, I want old and new documents to coexist in the collection, while using only new version of c# model to read them. I wish no inheritance is used if possible. So I wonder which of this issues are solvable and how:
there is a new property in c# model which does not present in database. I think it never should be an issue, Mongo knows nothing about it, and it will be initialized with default value. The only issue here is to initialize it with particular value for all old documents, anybody knows how?
one of property has gone from model. I want MongoDb to find out there is no more property in c# class to map the field of old document to, and to ignore it instead of crashing. This scenario probably sounds a bit strange as it would mean some garbage left in database, but anyway, is the behavior possible to implement/configure?
type if changed, new type is convertible to old one, like integer->string. Is there any way to configure mapping for old docs?
I can consider using inheritance for second case if it is not solvable otherwise
Most of the answers to your questions are found here.
BsonDefaultValue("abc") attribute on properties to handle values not present in the database, and to give them a default value upon deserialization
BsonIgnoreExtraElements attribute on the class to ignore extra elements found during deserialization (to avoid the exception)
A custom serializer is required to handle if the type of a member is changed, or you need to write an upgrade script to fix the data. It would probably be easier to leave the int on load, and save to a string as needed. (That will mean that you'll need a new property name for the string version of the property.)
Fluent builder is a well-known pattern to build objects with many properties:
Team team = teamBuilder.CreateTeam("Chelsea")
.WithNickName("The blues")
.WithShirtColor(Color.Blue)
.FromTown("London")
.PlayingAt("Stamford Bridge");
However, using it doesn't seem very clear to me due to one particular reason:
Every Team object has its minimal operational state, in other words, set of properties which have to be set (mandatory), so that the object is ready to use.
Now, how should the Fluent builder approach be used considering that you have to maintain this state?
Should the With_XYZ members modify the part of the object, that can't affect this state?
Maybe there are some general rules for this situation?
Update:
If the CreateTeam method should take the mandatory properties as arguments, what happens next?
What happens if I (for example) omit the WithNickName call?
Does this mean that the nickname should be defaulted to some DefaultNickname?
Does this mean that the example (see the link) is bad, because the object can be left in invalid state?
And, well, I suspect that in this case the fluent building approach actually loses it's "beauty", doesn't it?
CreateTeam() should have the mandatory the properties as parameters.
Team CreateTeam(string name, Color shirtColor, string Town)
{
}
Seems to me the points of Fluent Interface are:
Minimize the number of parameters to zero in a constructor while still dynamically initializing certain properties upon creation.
Makes the property/ parameter-value association very clear - in a large parameter list, what value is for what? Can't tell without digging further.
The coding style of the instantiation is very clean, readable, and editable. Adding or deleting property settings with this formatting style is less error prone. I.E. delete an entire line, rather than edit in the middle of a long parameter list; not to mention editing the wrong parameter
So, I've been searching around on the internet for a bit, trying to see if someone has already invented the wheel here. What I want to do is write an integration test that will parse the current project, find all references to a certain method, find it's arguments, and then check the database for that argument. For example:
public interface IContentProvider
{
ContentItem GetContentFor(string descriptor);
}
public class ContentProvider : IContentProvider
{
public virtual ContentItem GetContentFor(string descriptor)
{
// Fetches Content from Database for descriptor and returns in
}
}
Any other class will get an IContentProvider injected into their constructor using IOC, such that they could write something like:
contentProvider.GetContentFor("SomeDescriptor");
contentProvider.GetContentFor("SomeOtherDescriptor");
Basically, the unit test finds all these references, find the set of text ["SomeDescriptor", "SomeOtherDescriptor"], and then I can check the database to make sure I have rows defined for those descriptors. Furthermore, the descriptors are hard coded.
I could make an enum value for all descriptors, but the enum would have thousands of possible options, and that seems like kinda a hack.
Now, this link on SO: How I can get all reference with Reflection + C# basically says it's impossible without some very advanced IL parsing. To clarify; I don't need Reflector or anything - it's just to be an automated test I can run so that if any other developers on my team check in code that calls for this content without creating the DB record, the test will fail.
Is this possible? If so, does anyone have a resource to look at or sample code to modify?
EDIT: Alternatively, perhaps a different method of doing this VS trying to find all references? The end result is I want a test to fail when the record doesnt exist.
This will be very difficult: your program may compute the value of the descriptor, which will mean your test is able to know which value are possible without executing said code.
I would suggest to change the way you program here, by using an enum type, or coding using the type safe enum pattern. This way, each and every use of a GetContentFor will be safe: the argument is part of the enum, and the languages type checker performs the check.
Your test can then easily iterate on the different enum fields, and check they are all declared in your database, very easily.
Adding a new content key requires editing the enum, but this is a small inconvenient you can live with, as it help a log ensuring all calls are safe.
I'm developing an application that does some CRUD operations through a WCF service. The read method returns a complete entity, the update is performed through a legacy system, and only the changed values should be updated.
What is the best way to design the data contract for this scenario without simply sending a dictionary of key-value pairs?
The only other thing I can think of is to make your component durable - i.e. persist its state to a file or database. That way, on the update you can compare the previous state to the state being passed in. I'm not sure that's a good way to go since it will introduce more overhead than just passing in the key-value pairs.
From the outside it might look more CRUDy or whatever, but from a practical standpoint you may be better off just passing some indication as to which values changed.
In case it helps, not sure exactly what you're looking for though ...
In the update request, only act upon fields that are not null.
In addition wrap any non-nullable types in a nullable structure.
As an example ...
Update( Nullable<int> orderNumber,
Nullable<DateTime> orderDate,
Nullable<bool> isComplete )
{
if( orderNumber != null )
databaseRecord.OrderNumber = orderNumber;
if( orderDate != null )
databaseRecord.OrderDate = orderDate;
if( isComplete != null )
databaseRecord.IsComplete = isComplete;
}
the best way to do this is with property dictionary, just represent your entities as dictionary of property name and value.
save all changes in some list and pass a partial dictionary with all changed properties.
i think this is best design,
if u wanna avoid this design, send entire entity with some list of changed properties.
(to save transport u can put null on other properties)
if u don't wanna change the service contract signature u can push the names of modified properties on the header
I had two ideas of how to achieve this;
Have the client send both the original entity, and the changed entity in full, the service would then figure out what properties were changed.
Use a pattern similar to Nullable, lets call it Modified with an IsModified flag and a NewValue property of type T. Each property of the DataContract would be of this type, the service can check the IsModified flag when performing the update.
The legacy sytem we use has an api that accepts String.Empty to identify unmodified fields, a '?' character is used to indicate an update to an empty string. I really don't like this, the user of the api is forced to read the documentation, and if you actually want to store a '?' you can't. I want our webservice api to be more explicit.
You can use DataSet to keep your changes. Call your record as DataSet then assign some values to the record. DataSet.Tables[0].GetChanges() will give you the columns which were changed.
You could leave the data contract alone and update your service contract. Just represent the required fields for the method as properties within the service contract. Any consuming application using the service will have to be updated if the service contact changes, but the consuming application will know what is required to successfully update the data.
There are positives and negatives to this method, but I use it when a method I am writing doesn't require the full data contract.
--Edited for a spelling error--
Looking at your requirements and statements, i've made a few assumptions before starting to write my vision on a possible solution:
You are using the same class for retrieving (return value type of "read" operation) and updating an item (input parameter type of "update" operation) in your WCF service.
Your current problem of implementation is how to use the original class (not a dictionary) AND still be able to determine 'what has changed compared to the read' when you get the "Update" operation called on your WCF service
You are writing both the server and client. Both are written using the MS .Net framework.
If this is true, the problem lies in the Update method missing information. The information required is 'has changed' which could be inferred if a 2nd state is present to compare against or should already be present along side the state to update in the back-end.
Since you only have the 'back-end state' (without flags) when the client posts its data to the WCF service, how should we determine what did change? Obviously, we want to prevent another 'read' roundtrip to get the current server state and start comparing.
Sending the original & changed state from the client to the server is a possible but heavy solution. Next to that, the client isn't interrested in this information, the server is.
Adding this all up makes my guess is that changing the type of the 'Update' operation input parameter is the easiest way to go. Create a decorator class that adds 'dirty bit' behavior to the original entity. Use this new class as input parameter for your "Update" operation. You then will have the availability in the server to check this dirty bit next to the full state send by the client. The major change on the client side is that the object needed for the 'Update' operation is no longer the same as the one provided by the 'Read' method. To eleviate this pain, i would probably create a decorator class which added the required 'dirty bit' handling. This only requires the object instanciation to change, while maintaining the interface signature for the client (very little code changes).