In my project I have a header class that represents a globally unique key for a piece of information inside the system, such as who it belongs to, what time it exists for, etc. Inside the same header class I also have fields for information that is specific to a given instance of data, such as who created this version of the information, when it was created, if its new data that needs to be saved to the database, etc.
Here is an example of stocking some information into a data transport class and querying it back out.
var header = new IntvlDataHeader(
datapoint: Guid.NewGuid(),
element: Guid.NewGuid(),
intervalUtc: DateTime.Now.Date);
package.StockData_Decimal(header, 5m);
decimal cloneData;
package.TryGetData_Decimal(ref header, out cloneData);
// header now refers to a different object, that could have different flags/information
Note how I made the TryGetData_Decimal pass the header variable by reference. IntvlDataHeader is a class, and if the data is found inside TryGetData then the reference is changed to point to a new instance of IntvlDataHeader that has the specific instance information in addition to having the same unique key information.
Is combining a key with instance specific information and using a ref parameter as both in and out a bad design? Would the effort of splitting out another class so that there would be two out parameters and no ref parameters be better or avoid any potential problems?
The signature of the method is public bool TryGetData_Decimal(ref IntvlDataHeader header, out decimal data)
I think the naming of your TryGetData_Decimal is misleading, if the ref parameter your passing in will then point to a new instance when the method exits. TryGetData_Decimal, to me, sounds like a variation of the TryParse methods on a number of value types (which has an out parameter containing the parsed value - similar to the cloneData parameter).
I guess I'm not sure why the header object has to point to a new instance, so I'm not sure I can recommend a design. If that's what you need to do, I think it may be more readable if your TryGetData_XXX methods have a signature something like this:
IntvlDataHeader ExtractValueAndGetNewInstance_Decimal(IntvlDataHeader header, out decimal cloneData)
where header is passed in, but doesn't change when the method exits. The method returns the new instance, and you can use it if you need it. I wouldn't change the cloneData - I think out parameters are OK as long as they aren't overused.
I'd try to change the name of the method to something more meaningful, too.
I hope this helps.
Related
When using DoFixture I can set a domain object as System Under Test which allows me to call methods on that object instead of the fixture itself.
Unfortunately, if such a method requires more than one parameter I have to separate those parameters with empty cells because otherwise fitnesse/fitSharp uses odd/even cells to build up the method name. I can see how this makes my tests to resemble plain English better, but it's not really feasible to start renaming domain object methods just to satisfy test framework requirements.
For example, say I want to call method Entry AddEntry(string name, string description) and store the result as symbol e1. If I try the following table:
|name|e1|add entry|sample name|sample description|
it will try to find a method named AddEntrySampleDescription and pass it a single parameter "sample name".
I can do
|name|e1|add|sample name|entry|sample description|
but it just doesn't look right.
So, what I ended up doing is (note the extra empty cell between the parameters)
|name|e1|add entry|sample name||sample description|
which does what I want and isn't as ugly as the option #2 but it still seems like a hack. Do I miss something or is that actually the way to call methods on domain objects?
You can add the empty cell between parameters - this is a widely-used technique. Or you can use SequenceFixture:
http://fitnesse.org/FitNesse.UserGuide.FixtureGallery.FitLibraryFixtures.SequenceFixture
SequenceFixture is very similar to DoFixture and has almost the same
features — in fact the only difference between those two is the naming
convention for methods. Instead of using odd cells to construct a
method name, SequenceFixture takes the first cell in each row as the
method name, and all other cells as arguments
When I'm evaluating a SharePoint list's custom field of type 'User' I'd expect to only get the username but instead I'm seeing additional characters at the start that I need to trim out.
SPContext.Current.ListItem[NameOfUserField] has the value of
"14;#DeeMac"
And as a side note - this field is being treated as a string - but in my xml files I've defined it as a 'User' field type - where and why has this conversion been made? I did originally try to cast it as SPFieldUser which failed.
The first part of the string is that user's ID in the SPWeb in question. I.e. DeeMac is, roughly speaking, the 14th person to use that web.
In order to get an SPUser object from that string, you need to take the SPWeb to which the user belongs and call the SPFieldUserValue(SPWeb, string) constructor with the two.
The SPFieldUserValue thus constructed contains a User property of type SPUser, which may be null if the string was null/empty.
Note that sometimes, I think, a user column may actually contain SPFieldUserValue objects already, instead of strings.
Also if it's a multi-user column, it might contain a SPFieldUserValueCollection object or a string to pass into that class's constructor.
If you ever run into issues, debug and check what's actually in your column.
I want to make a Configuration Data Manager. This would allow multiple services to store and access configuration data that is common to all of them.
For the purposes of the Manager, I've decided to create a configuration class object - basically what every configuration data entry would look like:
Name, type, and value.
In the object these would all be strings that discribe the configuration data object itself. Once it has gotten this data from its database as strings, it would put it into this configuration object.
Then, I want it to send it through WCF to its destination. BUT, I don't want to send a serialized version of the configuration object, but rather a serialized version of the object discribed by the configuration object.
The reason I'd like to do this is so that
The Data Manager does not need to know anything about the configuration data.
So I can add configuration objects easily without changing the service. Of course, I should be able to do all of the CRUD operations, not just read.
Summary:
Input: string of name, type and value
Output: Serialized output of the object; the object itself is "type name = value"
Questions:
Is this a good method for storing and accessing the data?
How can I/can I serialize in this manner?
What would the function prototype of a getConfigurationData method look like?
I have decided to go in a different direction, thanks for the help.
Is this a good method for storing and accessing the data?
That is difficult to answer, the best I can give you is both a "yes" and a "No". Yes, It's not a bad idea to isolate the serialization/rehydration of this data.... and No, I don't really care much for the way you describe doing it. I'm not sure I would want it stored in text unless I plan on editing it by hand, and if I'm editing it by hand, I'm not sure I'd want it in a database. It could be done; just not sure you're really on the right track yet.
How can I/can I serialize in this manner?
Don't build your own, never that. Use a well-known format that already exists. Either XML or JSON will serve for hand-editable, or there are several binary formats (BSON, protobuffers) if you do not need to be able to edit it.
What would the function prototype of a getConfigurationData method look like?
I would first break-down the 'general' aka common configuration into a seperate call from the service specific configuration. This enables getConfigurationData to simply return a rich type for common information. Then either add a extra param and property for service specific data, or add another method. As an example:
[DataContract]
public class ConfigurationInfo
{
[DataMember]
public string Foo;
...
// This string is a json/xml blob specific to the 'svcType' parameter
[DataMember]
public string ServiceConfig;
}
[DataContract]
public interface IServiceHost
{
ConfigurationInfo GetConfigurationData(string svcType);
}
Obviously you place a little burden on the caller to parse the 'ServiceConfig'; however, your server can treat it as an opaque string value. It's only job is to associate it with the appropriate svcType and store/fetch the correct value.
the application is very large so giving a brief back ground and the problem
when the user logs in, a button is displayed having the text of the function he is allowed to call.
the function he is allowed is mapped in the database table
its made sure that the name of the actual function is same to the ones used in the db.
problem
the name is extracted, and stored as text field of button and also in a string variable.
now how am i supposed to call this function using the string variable which has the name stored in it!
like we type
name-of-function();
but here i dont know the name, the string at run time does so i cant write like
string()!!?
You will need to use reflection to do this. Here is a rough sketch of what you need to do:
// Get the Type on which your method resides:
Type t = typeof(SomeType);
// Get the method
MethodInfo m = t.GetMethod("methodNameFromDb");
// Invoke dynamically
m.Invoke(instance, null);
Depending on your actual needs you will have to modify this a little - lookup the used methods and types on MSDN: MethodInfo, Invoke
Well, no matter what you do, there is going to have to be some kind of mapping done between a database "function" and your "real" function. You can probably use Reflection using your Types and MethodInfo.
However, this sounds like a maintenance nightmare. It also sounds like you are reinventing user roles or the like. I would be very cautious about going down this path - I think it will be much more complex and problematic than you think.
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).