I've got a class hierarchy in C# describing some data structure. There are base classes, which automate and perform some general tasks and on top of them there are specialized classes, which reflect the actual structure.
I want that structure to be able to be loaded only once. If you load it - or modify any of its fields - loading should no longer be available.
I came up with three solutions:
Create a flag bool loaded field and set it when class is loaded (or changed).
Pros: Structure does not have to be changed from what it currently is, straightforward usage (new + .Load())
Cons: I would have to work hard to propagate this flag throughout the whole structure and generally take care of it, such that it would be updated in every possible case. Also, this is runtime solution (second load = exception), while I always prefer compile-time solutions.
Move the loading to constructor of class, such that one might create an empty structure or create it and load immediately after.
Pros: Compile-time solution: one would not be able to simply load the structure at any time.
Cons: Loading relies on derived classes and virtual methods cannot be called in the constructor, what complicates things. This can be overcome, but in the cost of simplicity of the interface. Also it happens, that while loading, I have to return a object, what would require the ctor to have an out parameter (that seems to be a necessity anyway).
Create class factory, hide the ctor and provide factory methods for creating empty and pre-loaded structure.
Pros: Compile-time solution. Factory can be generic to cover all derived classes
Cons: Complicated code and non-intuitive interface (factories are a little less obvious way to create things than new operator). Also, this solution relies on internal modifier to make the structure and factory friends.
My questions are:
Is there a better way to prevent one from loading a structure a few times?
Or: is there a way to overcome downsides of proposed solutions?
Edit: In response to answers
Think of my structure as of Word document or Excel sheet. Word document can only be loaded once, you cannot "call load" on already loaded document. This is a kind of security measure I want. In other words I want to prevent someone from calling:
MyStructure s = new MyStructure();
s.Load("file1.str");
s.Load("file2.str"); // Doesn't make sense
And also:
MyStructure s = new MyStructure();
s.SomeProperty = 15;
s.Load("file1.str"); // Doesn't make sense
You should use an Identity Map for that. It keeps track of which entities have already been loaded.
Additional cons:
1 - Your data object is no longer holding just business data - it's also holding a loaded state - this is against the SRP.
3 - Factories may have to change when more types are created - this will mean more maintenance
It looks like you are using the active record pattern. I would not use the active record pattern as it combines business data and data loading - this is against the SRP.
Instead, use the repository pattern with POCOs to create your objects.
However, if you are keeping the current code you could add checks in the Load method - if the file name is different to the current file name (surely a property) prevent the load because it doesn't make sense in this context.
I want that structure to be able to be loaded only once.
Have you looked at the Singleton pattern?
The singleton pattern restricts the instantiation of a class to one object. Using the pattern will ensure you are not re-inventing the wheel.
However, I am not sure if you really only want one object in your application, or you want to ensure your code doesn't retrieve the data more than once for performance reasons - hence two answers.
Related
Using Protobuf-net, I want to know what properties of an object have been updated at the end of a merge operation so that I can notify interested code to update other components that may relate to those updated properties.
I noticed that there are a few different types of properties/methods I can add which will help me serialize selectively (Specified and ShouldSerialize). I noticed in MemberSpecifiedDecorator that the ‘read’ method will set the specified property to true when it reads. However, even if I add specified properties for each field, I’d have to check each one (and update code when new properties were added)
My current plan is to create a custom SerializationContext.context object, and then detect that during the desearalization process – and update a list of members. However… there are quite a few places in the code I need to touch to do that, and I’d rather do it using an existing system if possible.
It is much more desirable to get a list of updated member information. I realize that due to walking down an object graph that may result in many members, but in my use case I’m not merging complex objects, just simple POCO’s with value type properties.
Getting a delta log isn't an inbuilt feature, partly because of the complexity when it comes to complex models, as you note. The Specified trick would work, although this isn't the purpose it was designed for - but to avoid adding complexity to your own code,that would be something best handled via reflection, perhaps using the Expression API for performance. Another approach might be to use a ProtoReader to know in advance which fields will be touched, but that demands an understanding of the field-number/member map (which can be queried via RuntimeTypeModel).
Are you using habd-crafted models? Or are you using protogen? Yet another option would be to have code in the setters that logs changes somewhere. I don't think protogen currently emits partial method hooks, but it possibly could.
But let me turn this around: it isn't a feature that is built in right now, and it is somewhat limited due to complexity anyway, but: what would a "good" API for this look like to you?
As a side note: this isn't really a common features in serializers - you'd have very similar challenges in any mainstream serializer that I can think of.
I have to apply [Serializable()] attribute for all classes, but I want to know is there any way to make classes Serializable globally instead of applying this attribute individually for all classes?
No, there isn't a way of applying this globally - you'd have to visit each type and add the attribute.
However: applying this globally is a really, really bad idea. Knowing exactly what you're serializing, when, and why is really important - whether this is for session-state, primary persistence, cache, or any other use-case. Statements like
I have to apply [Serializable()] attribute for all classes
tells me that you are not currently in control of what you are storing.
Additionally, since [Serializable] maps (usually) to BinaryFormatter, it is important to know that there are a lot of ways (when using BinaryFormatter) in which it is possible to accidentally drag unexpected parts of your model into the serialized data. The most notorious of these is "events", but: there are others.
When I see this type of question, what I envisage is that you're using types from your main data model as the thing that you are putting into session-state, but frankly: this is a mistake - and leads to questions like this. Instead, the far more maneagable approach is to create a separate model that exists purely for this purpose:
it only has the data that you need to have available in session
it is marked [Serializable] if your provider needs that - or whatever other metadata is needed for the sole purpose for which it exists
it does not have any events
it doesn't involve any tooling like ORM contexts, database connections etc
ideally it is immutable (to avoid confusion over what happens if you make changes locally, which can otherwise sometimes behave differently for in-memory vs persisted storage)
just plain simple basic objects - very easy to reason about
can be iterated separately to your main domain objects, so you don't have any unexpected breaks because you changed something innocent-looking in your domain model and it broke the serializer
I was often wondering about the right way to do this:
For example, in my program I have around 100 constants (or enums) that are used in some calculation. They should preferrably be stored in one place. They can be grouped hierarchically, for example:
System3 / Rules / Rule7 / ParameterXY / MaxAverageValue
Naturally, I want those values to be accessible while coding, so storing them in some kind of ressource is not really an option.
As far as I could tell, this can be done with:
very long constant names
nesting classes
namespaces
Using names is quite ugly, and it's not really well maintainable. I find nesting classes a nice way to do it, but some stylecop/fxcop rules forbid that, so this must be "bad" in some way. Lastly, I find the suggested alternative, using namespaces, not terribly nice neither. Imho it creates masses of folders and files that each contain almost nothing. And I don't like when 50 sub-namespaces pop up in the assembly reflector.
So.. how do you do this kind of task? What would you suggest?
very long constant names
This is sort of gross, but at least it is discoverable. All your code would reside in the same place so you wouldn't have a problem finding it.
I find nesting classes a nice way to do it, but some stylecop/fxcop rules forbid that, so this must be "bad" in some way
One reason it is is bad because automated code generation/code inspection tools are harder to work with. Another reason is that it is harder to discover these with Intellisense.
The most important reason this is bad is because a nested class should be strongly associated in an object-oriented dependency sense for the layout be make sense logically. In all but some rare cases (e.g. Enumerator classes) it won't make sense. In your case it also doesn't make sense because your classes don't really have any behavior or object orientation at all - they're just a hierarchy of constants.
Namespaces
For the problem you described, this is the best way to handle it. You get the least clutter per-level, and you get Intellisense while typing so you can see what you're narrowing down to while descending through the hierarchy.
Imho it creates masses of folders and files that each contain almost nothing
If you really need a huge pool of constants, and it doesn't make sense to bind them to other parts of your application, then this is one of the rare cases that I'd abuse the one-file-per-class and one-folder-per-namespace rules. The only reason you're even stuffing them into classes at all is because .Net doesn't have support for global variables.
Another suggestion
Do you have domain-specific objects that these constants belong on instead? E.g. is there any logic related to the System3 / Rules / Rule7 class? Is that not some sort of actual business rule that you should embody with its own class?
If you can arrange your code so that you have a thicker domain model, then the most logical place to put your constants is on the classes that embody the corresponding domain logic.
If it doesn't make sense to have a thick domain, you have fully generic rules processing, and you are relying on constants to feed your business engine logic, then you have a data-driven application. This means you should store your data in configuration files, not in code.
How often is each constant re-used in multiple methods? You could consider reorganizing your constants. If you still find yourself with huge numbers of constants, try putting them in a static class with read-only properties.
If you just need a good place to look at them all in one place, you could also look at storing them in the app.config file and you can access them through AppSettings and the ConfigurationManager class.
Well the way I do this is to have a sealed file called Constants.
so
public sealed class Constants
{
//for e.g.
//Sessions
public const string APPSESSIONKEY = "AppType";
}
Than I use this in the rest of my project and the importance here is what you will name it as it will help you remember it and make sense when you need it.
By calling it in your code.
Constants.AppSessionKey
You could also
Create an Assembly whose only purpose is to hold constant values for the project. Every other Assembly should then reference this one. Following DRY and KISS, since adding references is simple enough. Main problem here is recompilation.
We use Resources files with a custom T4 template that generates a static class hierarchy with readonly string fields for the values.
The keys in our Resource file are separated with '.' to build the hierarchy.
We can have separate resource files that are compiled into one class hierarchy.
I know that nested classes is not recommended but in my opinion, for a situation like this it is the nicest solution.
I like to implement a collection (something like List<T>) which would hold all my objects that I have created in the entire life span of my application as if its an array of pointers in C++. The idea is that when my process starts I can use a central factory to create all objects and then periodically validate/invalidate their state. Basically I want to make sure that my process only deals with valid instances and I don't re-fetch information I already fetched from the database. So all my objects will basically be in one place - my collection. A cool thing I can do with this is avoid database calls to get data from the database if I already got it (even if I updated it after retrieval its still up-to-date if of course some other process didn't update it but that a different concern). I don't want to be calling new Customer("James Thomas"); again if I initted James Thomas already sometime in the past. Currently I will end up with multiple copies of the same object across the appdomain - some out of sync other in sync and even though I deal with this using timestamp field on the MSSQL server I'd like to keep only one copy per customer in my appdomain (if possible process would be better).
I can't use regular collections like List or ArrayList for example because I cannot pass parameters by their real local reference to the their existing Add() methods where I'm creating them using ref so that's not to good I think. So how can this be implemented/can it be implemented at all ? A 'linked list' type of class with all methods working with ref & out params is what I'm thinking now but it may get ugly pretty quickly. Is there another way to implement such collection like RefList<T>.Add(ref T obj)?
So bottom line is: I don't want re-create an object if I've already created it before during the entire application life unless I decide to re-create it explicitly (maybe its out-of-date or something so I have to fetch it again from the db). Is there alternatives maybe ?
The easiest way to do what you're trying to accomplish is to create a wrapper that holds on to the list. This wrapper will have an add method which takes in a ref. In the add it looks up the value in the list and creates it when it can't find the value. Or a Cache
But... this statement would make me worry.
I don't want re-create an object if
I've already created it before during
the entire application life
But as Raymond Chen points out that A cache with a bad policy is another name for a memory leak. What you've described is a cache with no policy
To fix this you should consider using for a non-web app either System.Runtime.Caching for 4.0 or for 3.5 and earlier the Enterprise Library Caching Block. If this is a Web App then you can use the System.Web.Caching. Or if you must roll your own at least get a sensible policy in place.
All of this of course assumes that your database's caching is insufficient.
Using Ioc will save you many many many bugs, and make your application easier to test and your modules will be less coupled.
Ioc performance are pretty good.
I recommend you to use the implementation of Castle project
http://stw.castleproject.org/Windsor.MainPage.ashx
maybe you'll need a day to learn it, but it's great.
I need to work on an application that consists of two major parts:
The business logic part with specific business classes (e.g. Book, Library, Author, ...)
A generic part that can show Books, Libraries, ... in data grids, map them to a database, ...).
The generic part uses reflection to get the data out of the business classes without the need to write specific data-grid or database logic in the business classes. This works fine and allows us to add new business classes (e.g. LibraryMember) without the need to adjust the data grid and database logic.
However, over the years, code was added to the business classes that also makes use of reflection to get things done in the business classes. E.g. if the Author of a Book is changed, observers are called to tell the Author itself that it should add this book to its collection of books written by him (Author.Books). In these observers, not only the instances are passed, but also information that is directly derived from the reflection (the FieldInfo is added to the observer call so that the caller knows that the field "Author" of the book is changed).
I can clearly see advantages in using reflection in these generic modules (like the data grid or database interface), but it seems to me that using reflection in the business classes is a bad idea. After all, shouldn't the application work without relying on reflection as much as possible? Or is the use of reflection the 'normal way of working' in the 21st century?
Is it good practice to use reflection in your business logic?
EDIT: Some clarification on the remark of Kirk:
Imagine that Author implements an observer on Book.
Book calls all its observers whenever some field of Book changes (like Title, Year, #Pages, Author, ...). The 'FieldInfo' of the changed field is passed in the observer.
The Author-observer then uses this FieldInfo to decide whether it is interested in this change. In this case, if FieldInfo is for the field Author of Book, the Author-Observer will update its own vector of Books.
The main danger with Reflection is that the flexibility can escalate into disorganized, unmaintainable code, particularly if more junior devs are used to make changes, who may not fully understand the Reflection code or are so enamored of it that they use it to solve every problem, even when simpler tools would suffice.
My observation has been that over-generalization leads to over-complication. It gets worse when the actual boundary cases turn out to not be accommodated by the generalized design, requiring hacks to fit in the new features on schedule, transmuting flexibility into complexity.
I avoid using reflection. Yes, it makes your program more flexible. But this flexibility comes at a high price: There is no compile-time checking of field names or types or whatever information you're collecting through reflection.
Like many things, it depends on what you're doing. If the nature of your logic is that you NEVER compare the field names (or whatever) found to a constant value, then using reflection is probably a good thing. But if you use reflection to find field names, and then loop through them searching for the fields named "Author" and "Title", you've just created a more-complex simulation of an object with two named fields. And what if you search for "Author" when the field is actually called "AuthorName", or you intend to search for "Author" and accidentally type "Auhtor"? Now you have errors that won't show up until runtime instead of being flagged at compile time.
With hard-coded field names, your IDE can tell you every place that a certain field is used. With reflection ... not so easy to tell. Maybe you can do a text search on the name, but if field names are passed around as variables, it can get very difficult.
I'm working on a system now where the original authors loved reflection and similar techniques. There are all sorts of places where they need to create an instance of a class and instead of just saying "new" and the class, they create a token that they look up in a table to get the class name. What does this gain? Yes, we could change the table to map that token to a different name. And this gains us ... what? When was the last time that you said, "Oh, every place that my program creates an instance of Customer, I want to change to create an instance of NewKindOfCustomer." If you have changes to a class, you change the class, not create a new class but keep the old one around for nostalgia.
To take a similar issue, I make a regular practice of building data entry screens on the fly by asking the database for a list of field names, types, and sizes, and then laying it out from there. This gives me the advantage of using the same program for all the simpler data entry screens -- just pass in the table name as a parameter -- and if a field is added or deleted, zero code change is required. But this only works as long as I don't care what the fields are. Once I start having validations or side effects specific to this screen, the system is more trouble than it's worth, and I'm better off to fall back to more explicit coding.
Based on your edit, it sounds like you are using reflection purely as a mechanism for identifying fields. This is as opposed to dynamic behavior such as looking up the fields, which should be avoided when possible (since such lookups usually use strings which ruin static type safety). Using FieldInfo to provide an identifier for a field is fairly harmless, though it does expose some internals (the info class) in a way that is not entirely ideal.
I tend not to use reflection where i can help it. by using interfaces and coding against these i can do a lot of things that some would use reflection for.
But im a big fan of if it works, it works.
Also by using reflection you probably have something that can adapt fairly easily.
Ie the only objection most would have is fairly religious ... and if your performance is fine and the code is maintainable and clear .... who cares?
Edit: based on your edit i would indeed use interfaces to achieve what you want. Unless i misunderstand you.
I think it is a good idea to stay away from Reflection when possible, but dont be afraid to resort to it when it provides a better or more flexible solution to your problem. The performance hit for anything but tight loop operations is likely to be minimal in the overall scheme of an application or Web Form request.
Just a good article to share about reflection -
http://www.simple-talk.com/dotnet/.net-framework/a-defense-of-reflection-in-.net/
I tend to use interfaces in my business layer and leave the reflection to my presentation layer. This is not an absolute but rather a guideline.