Best way to create a complete readOnly list of object - c#

I'm using C# 4.0, Asp.Net. I have a problem regarding the proper construction of a readonly structure within a custom cache I created.
Details (summary) :
My CacheManager class (singleton) uses, as parameter, an instance of the existing MemoryCache class and wraps around a few helpful methods to deal with supplementary stuff such as object life cycle within my custom cache.
That Manager deals with a simple CachableObject that takes three variables :
object
DateTime
int (duration)
In summary, my custom cache Manager stores objects for a limited amount of time in order to protect my database from frequent big queries.
Lately, I tried to :
Got back an object from the cache (ie : stored under the key -MyList)
Casted it back to a list of complexe objects
Translated the content of some properties for each complexe objects
Stored again the freshly translated list of objects within the cache, (under another key -MyTranslatedList)
The problem :
During my testing, it appeared to me that both lists stored in the cache (raw and translated one) were refering to the same underlying objects. Therefore, once translated, those objects were actually translated in both lists.
Since each list only has references to the objects, that's a perfectly normal behavior and a silly mistake from me.
The question :
As you can easily guess now, I would like to protect myself and other users of my singleton for that kind of mistakes.
I would like to insert (or store or get) any kind of object (or list of complexe objects) so they cannot be altered by anybody getting them through the cache. I would like the data within my cache to be readonly (and deeply readonly) to avoid having that kind of problem. I want anybody to have to create a deep copy (or even better, to get one) before starting to use the data stored within the cache.
What I tried so far :
I tried to make the object readonly. It didn't work as expected.
Since I'm often storing list of complexe objects, I've found the AsReadOnly method that return a IReadOnlyCollection, but while this prevents me from altering the list (add, remove) it doesn't protect the objects that are within the list.
I hope my explanation is somewhat understandable :) Is there a neat way of dealing with that kind of situation ?

I would create a class where the properties are readonly:
class ReadonlyClass
{
private string p1;
private int p2;
public ReadonlyClass(string property1, int property2)
{
p1 = property1;
p2 = property2;
}
public string Property1
{
get { return p1; }
}
public int Property2
{
get { return p2; }
}
}
If the properties are objects/other classes, you should implement a clone function that returns a copy of the object. The clone function for the above class would looke like this:
public ReadonlyClass clone()
{
return new ReadonlyClass(p1, p2);
}
Best regards
Hans Milling...

Related

Large class with dependant classes and shared properties

I am having trouble figuring out the best way to refactor a very large C# class and specifically how to pass shared properties/values from the large class into the extracted classes and have those modified values available in the main class.
At the start, this class was 1000 lines long and is very procedural – it involves calling methods and performing work in a specific sequence. Along the way things are persisted into the database. During the process there are multiple Lists of items that are worked on and shared in the methods. At the end of this process, there are a bunch of statistics that are presented to the user. These statistics are calculated in various methods as the processing is taking place. To give a rough outline – the process involves a bunch of random selection and at the end of the process the user sees how many random items, how many invalid records were picked, how many items came from this sub-list etc.
I have been reading Uncle Bob’s “Clean Code” and am trying to make sure as I refactor that each class does only 1 thing.
So I have been able to extract methods and classes in order to keep the file smaller (have it down to 450 lines now) but the problem I am having now is that these broken out classes require values from the main parent class to be passed to them and updated – these values will be used for other methods/class methods as well.
I am torn as to which is the cleanest approach:
1) Should I create a bunch of private member variables to store the statistical values and Lists in the main class and then after calling into the main class' dependnat class methods, receive back a complex result class and then extract these values out and populate / update the private member variables? ( lots of boiler plate code this way)
OR
2) Is it better to create a DTO or a some sort of container class that holds the Lists and statistical values and just pass it to the various class methods and child class methods by reference in order to build up the list of values? In other words I am just passing this container class and since it's an object the other classes and methods will be able to directly manipulate the values in there. Then at the end of the process, that values DTO/container/whatever you want to call it will have all of the final results in it and I can just extract them from the container class (and in that case there really is no need to extract them and populate the main class’ private member variables. )
The latter is the way I have it now but I am feeling that this is a code smell – it all works but it just seems “fragile”. I know large classes are not great but at least with everything in 1 large file it does seem clearer as to which properties I am updating etc.
-- UPDATE --
Some more info:
Unfortunately I can't post any of the actual code as it is propriatary - will try to come up with dummy example and paste it in if I get some time. One of the comments below mentioned refactoring the code into steps and that is exactly what I've done. The purpose of the class is ultimately 1 thing - to create a random list of things - so in the only public method that gets called for this class - I have refactored this down to 1 level of abtraction for each "step". Each step, whether that is a method in the same class, or if it makes sense to break it out into a helper class to do the substeps - it still requires access to the lists that get built up during the process and the simple counter variables that keep track of the statistics.
-- UPDATE --
Here is an attempt at showing something similar in code:
public class RandomList(){
public int Id{get; set;}
public int Name{get; set;}
public int NumOfInvalidItems {get; set;}
public int NumOfFirstChunkItems{get; set;}
public int NumOfSecondChunkItems{get; set;}
public ICollection<RandomListItem> Items{get; set;}
}
public class CreateRandomListService(){
private readonly IUnitOfWork _unitOfWork;
private readonly ICreateRandomListValidator _createRandomListValidator;
private readonly IRandomSubProcessService _randomSubProcessService;
private readonly IAnotherSubProcessService _anotherSubProcessService;
private RandomList _randomList;
public CreateRandomListService(IUnitOfWork unitOfWork,
ICreateRandomListValidator createRandomListValidator,
IRandomFirstChunkFactory randomFirstChunkFactory,
IRandomSecondChunkFactory randomSecondChunkFactory){
_unitOfWork = unitOfWork;
_createRandomListValidator = createRandomListValidator;
_randomFirstChunkService = randomFirstChunkFactory.Create(_unitOfWork);
_randomSecondChunkService = randomSecondChunkFactory.Create(_unitOfWork);
}
public CreateResult CreateRandomList(CreateRandomListValues createValues){
// validate passed in model before proceeding
if(_createRandomListValidator.Validate(createValues))
return new CreateResult({HasErrors:true});
InitializeValues(createValues); // fetch settings from db etc and build up
ProcessFirstChunk();
ProcessSecondChunk();
SaveWithStatistics();
createResult.Id = _randomList.Id;
return createResult;
}
private InitializeValues(CreateRandomListValues createValues){
_createValues = createValues;
_createValues.ImportantSetting = _unitOfWork.SettingsRepository.GetImportantSetting();
// etc.
_randomList = new RandomList(){
// set initial properties etc. some come from the passed in createValues, some from db
}
}
private void ProcessFirstChunk(){
_randomFirstChunkService.GetRandomFirstChunk(_createValues);
}
private void ProcessSecondChunk(){
_randomSecondChunkService.GetRandomSecondChunk(_createValues);
}
private void SaveWithStatistics(){
_randomList.Items _createValues.ListOfItems;
_randomList.NumOfInvalidItems = _createValues.NumOfInvalidItems;
_randomList.NumOfItemsChosen = _createValues.NumOfItemsChosen;
_randomList.NumOfFirstChunkItems = _createValues.NumOfFirstChunkItems;
_randomList.NumOfSecondChunkItems = _createValues.NumOfSecondChunkItems;
_unitOfWork.RandomThingRepository.Add(_randomList);
_unitOfWork.Save();
}
}
public class RandomFirstChunkService(){
private IUnitOfWork _unitOfWork;
public RandomFirstChunkService(IUnitOfWork unitOfWork){
_unitOfWork = unitOfWork;
}
public void GetRandomFirstChunk(CreateRandomListValues createValues){
// do processing here - build up list collection and keep track of counts
CallMethodThatUpdatesList(creatValues);
// how to return this to calling class? currently just updating values in createValues by reference
// can also return a complex class here and extract the values back to the main class' member
// variables
}
private void CallMethodThatUpdatesList(createRandomListValues createValues){
// do work
}
}
The brutal answer is that it depends... of course. It is hard to work out a answer without reading the code, but I would say that once you have created new classes (with one purpose) those classes and interfaces should define what data objects you need to pass around to solve your problems. And in that case it is strange for a method to return the same type as pass into it, I also think that manipulation one object through a seriers of methods is fragile. Imagine if each of you classes was a REST service; then how would those interfaces look like.
I wouldn't "pass stuff around". Nor would I break it up into separate classes just because its 1000 lines. You'll end up making it much messier and much more of a maintenance headache.
You didn't post your code (duh), so its hard to critique it. If you really go over it, I suspect you might have duplicate code in there that can be refactored into methods, etc.
If you've already gotten rid of the duplicate code, I'd next pull out all the database stuff into a DAL layer.
If you really want to make it smaller (based on what little info you provided), I'd next refactor it into "steps" and make a workflow type parent container class.
Again, hard to say without knowing the code.
I don't know how exactly you have managed to refactor the class this far, but from your explanation it sounds to me like the "statistic" is the concept that should become an object, something like:
interface IStatistic<TOutput>
{
IEnumerable<TOutput> Calculate(IEnumerable<input-type>);
}
When you wish to display some statistic, you just use the appropriate statistic:
return new MySpecial().Calculate(myData);
In case that statistics objects are not that easy to construct, e.i. they ask for some parameters and so, then you may supply a Func delegate which creates them:
void DoSomething(Func<IStatistic<string>> factory)
{
string[] inputData = ...
foreach (string line in factory().Calculate(inputData))
{
// do something...
}
}
As you are mentioning multiple lists, I suppose that input-type would actually be a couple of input types. If that is so, then it might really make sense to supply a kind of a DTO to just hold the lists:
class RawData
{
public IEnumerable<type1> Data1 { get; }
public IEnumerabel<type2> Data2 { get; }
...
}
Observe, however, that this is not a DTO "by the book". First, it is immutable - only getters are there. Second, it only exposes sequences (IEnumerable), rather than raw lists. Both measures are taken to disallow statistic objects to manipulate data.

C# immutability.. a lie?

It is one ideal practice in a multithreaded environment to clone objects (eg: a list) to promote immutability. However if we do so it can be a lie to the API users. What I'm saying is that..
Consider the following code:
public class Teacher {
public List<Student> Students = new List<Student>();
public Student GetStudent(int index) {
return Students[index].Clone();
}
}
public class Student {
public DateTime LastAttended { get; set; }
}
and the users of the API could have done so:
var teacher = new Teacher();
var student3 = teacher.GetStudent(3);
student3.LastAttended = DateTime.Now;
Without proper documentation the user could not have known the student object he is getting is actually a cloned object and in which case all changes made to the object will not reflect the original one.
How can the code above be improved in a way for the user to know intuitively that the GetStudent is meant only for reading and not for modification? Is there any way to force / restrict from modifying the Student object returned from the GetStudent method?
Your Student object isn't immutable at all. If you want immutability, make an immutable object:
public sealed class Student {
private readonly DateTime _lastAttended;
public DateTime LastAttended { get { return _lastAttended; } }
public Student(DateTime lastAttended)
{
_lastAttended = lastAttended;
}
}
If you don't want someone to set the value of a property, then do not expose a setter, only a getter.
This of course requires architecting the application around this. If you actually need to update the LastAttended time, you would do that e.g. through a Repository that updates the Database and returns a new Student object. Also, many ORMs can't automatically handle immutable objects and need some translation code.
Note that your issue is super-common when people cache objects in Memory and then pass them along, e.g. to View Models which manipulate them, unknowingly modifying the master-object in the cache. This is why cloning is often recommended for Caches. Cloning protects you from code making modifications to "your" objects - every time someone asks, they get a new instance of your master object. Cloning does not prevent the caller to mess up his own version.
Note that declaring a Field as readonly doesn't do much if the Type of the Field is a mutable type - I could still do e.g. Student.Course.Name = "Test"; even if Course were readonly - I cannot change the reference in the Student object, but I can access any property setters.
True immutability is a bit of a pain in C# as it's a lot of typing and a lot of factory methods. At some point, it may be okay to just leave a normal mutable Get/Set and trust that callers know what to do as they can only mess up themselves, not you. That said, anything that actually manipulates the data in the database needs proper security/business rule checks.

C# to use static class to create collection of the class or to use collection class

I have a design problem,
Basically, I have a class called Currency
public class Currency
{
public int ID;
public string Name;
public int RoundingValue;
public Currency() { }
public void GetData() { // Some SQL query code // }
}
Sometimes it is necessary to fetch all the currencies that there are in the system to make a decision concering exchange rates, compatability of payment, etc.
I see two ways of doing that (fetching data):
1) To make a static method inside Currency class to do it. That involves creating SQL connection instance inside it(not sure if that is the right thing to do), creating List<Currency> instance to store the collection, and then pass it outside the class.
2) Create collection of the class via extending Collections.BaseCollection class, make instance of it, doing the same SQL query, and then return the result. But that class will provide no additional functionality, and probably won't ever (the same for Currency itself.
In other cases, I used extended collections, because they needed to store additional info, based on the contents of the collection.
But in this case, no additional info is created or functionality provided.
So, what design would be more practical?
If there is an alternative to the these solutions, I would be more than happy to hear it.
I would suggest simply populating a List<Currency> then returning it as IList<Currency>. That way if you change it in future to use a custom collection, you won't break any consumers.

Associate "Code/Properties/Stuff" with Fields in C# without reflection. I am too indoctrinated by Javascript

I am building a library to automatically create forms for Objects in the project that I am working on.
The codebase is in C#, and essentially we have a HUGE number of different objects to store information about different things. If I send these objects to the client side as JSON, it is easy enough to programatically inspect them to generate a form for all of the properties.
The problem is that I want to be able to create a simple way of enforcing permissions and doing validation on the client side. It needs to be done on a field by field level.
In javascript I would do this by creating a parallel object structure, which had some sort of { permissions : "someLevel", validator : someFunction } object at the nodes. With empty nodes implying free permissions and universal validation. This would let me simply iterate over the new object and the permissions object, run the check, and deal with the result.
Because I am overfamilar with the hammer that is javascript, this is really the only way that I can see to deal with this problem. My first implementation thus uses reflection to let me treat objects as dictionaries, that can be programatically iterated over, and then I just have dictionaries of dictionaries of PermissionRule objects which can be compared with.
Very javascripty. Very awkward.
Is there some better way that I can do this? Essentially a way to associate a data set with each property, and then iterate over those properties.
Or else am I Doing It Wrong?
It sounds like you are describing custom attributes - i.e.
[Permissions("someLevel"), Validator("someFunction")]
public string Foo {get;set;}
This requires some reflection to read the attributes, but is quite a nice way of decorating types / members / etc. You might also look at the pre-rolled [PrincipalPermission] for security checks. Is this what you mean?
Note the above would require:
public class PermissionsAttribute : Attribute {
private readonly string permissions;
public string Permissions { get {return permissions;}}
public PermissionsAttribute(string permissions) {
this.permissions = permissions;
}
}
(and similar for the other)
You can read them out with Attribute.GetCustomAttributes

Data Structure for enumeration in c# where lookup is often predicated on one property of the Objects being stored

I'm wondering what Data Structure people would recommend to do the following. I have a Class which has three main properties eg.
public class Example {
public Object One { get; }
public Object Two { get; }
public Object Three { get; }
}
Another class contains a collection of these Objects and frequently needs to enumerate over these which I do mainly with LINQ. A lot of the time though I need to lookup/enumerate only a subset of these objects based mainly on the value of property One so what I'd like to do is store these in an efficient data structure based on that property. I could do something like the following:
Dictionary<Object,List<Example>>
But this strikes me as being very inefficient, I know I need some kind of Hash Table but having never used one before in C# I'm unsure of what there is to use.
Some other requirements/notes:
All the Objects are immutable and have fixed Hash Codes which are computed from the values the class gets instantiated with in the constructors
Must be able to store multiple items that have the same value (and thus Hash Code) for property One in the same 'slot' in the data structure
Must be able to freely add and remove Objects from the collection
Indexed LINQ may be able to help you here. It provides an in-memory collection, but lets you attribute properties on your objects as Indexable so that it can create efficient queries against them.
PowerCollections (http://www.codeplex.com/PowerCollections) has a MultiDictionary container - perhaps you could try that?
or HybridDictionary

Categories

Resources