Collections for multiple component types - c#

Can anyone answer a quick question for me? I'm working on a control that contains multiple types of subcontrol. This is so that it can represent a heirachial list.
--Group--
--Company--
--Site--
--Group--
Due to the increasing complexity I'm looking at the posssibility of using collections. I found an article on code project which covers this topic: http://www.codeproject.com/KB/cs/collcontrolsrichdes.aspx
There are 2 things that I am unsure of.
1) Is it possible to have components containing collecitons of their own (due to this heirachy)
2) Is there a way of making certain "types" optional. By this I mean, for example, a company sometimes a company may not have a group and may appear at the top of the heirachy.

Looks like you need a tree structure.
Here's a simple version:
class Group
{
List<Company> companies;
}
class Company
{
Group parentGroup;//Put at null if there is no parent
List<Site> sites;
}
class Site
{
Company parentSite;//Put at null if there is no parent
}

Related

Generate a unique ID to a body property of an object that's CONSISTENT through runtime and presents no overhead to the developer on implementation

This problem is a bit hard to expose via the title so I hope the following clarifies my intentions a bit.
Suppose you have the following data classes:
class abstract Employee {
string ID;
}
class FullTimeEmployee : Employee {
string schedule;
}
class PartTimeEmployee : Employee{
string schedulePartTime;
}
class WheelsSpecialist : Employee{ }
class InteriorsSpecialist : Employee{ }
class Workshop {
WheelsSpecialist wheely_guy;
InteriorsSpecialist interiors_guy;
}
Now, suppose that I instantiate my workshop as follows:
var Workshop = new Workshop{
wheely_guy = new PartTimeEmployee(),
interiors_guy = new FullTimeEmployee();
}
Please assume that the structure / inheritance and instantiations here provided are immutable.
What I'd like is to generate an ID set on Employee.ID that survives the runtime and is consist and independent from class properties / developer implementation.
Understand also that: The path of each object property in the workshop instantiation is guaranteed to be UNIQUE.
As so, a good ID for the WheelsSpecialist in Workshop.wheely_guy would be "Workshop.wheely_guy". (for example) because no path will ever be the same when I'm instantiating the workshop.
When I access the object "Workshop.wheely_guy.ID" I'd like to have "Workshop.wheely_guy" there or something analogous.
I imagine something like this would work (non valid C#, logic intact):
class PartTimeEmployee {
//instantiationPath is for example, "Workshop.wheely_guy"
onCreate(string instantiationPath){
this.ID = instantionPath;
}
}
I've tried this with StackTrace and whatnot, but couldn't find a way of doing it right.
Whether this instantiationPath method is used or not, the solution requires that:
I get to keep my structure as is in the example EXCEPT for properties. Those can change.
When I want to add a new dimension to my workshop variable I CAN'T, as a developer, be responsible for awarding a class it's own unique property.
As so, doing something like "this.ID = wheels" manually is not an option (also, depending this ID on properties that the developer must implement is also not viable).
Can this be done some way that meets my demands?
Thank you!
The provided code does not compile, and the object design/inheritance used seems a bit off. You probably want to work on the abstractions themselves. But that is not what you asked (mainly). It's kind of hard to figure out what exactly you asked, but I will do my best to answer what I think you asked (mostly):
"I want a field of an object instance to contain an automatically calculated navigation path by which it is accessible in some collection or composite object unrelated to the object itself" -> while close to impossible in C#, this might be entirely/easily possible in other languages. Still, the concept itself seems a little off.
The premise here is that the Employee object does not and should not know about the Workshop object Think about part-time employees trying to work separate shifts in separate workshops at the same time, and other possible changes in the business logic regarding Employees and Workshops.
Let's walk through some of the possibilities, ordered by viability:
Doing some magic at constructor/instantiation time in the abstract constructor code (Stack Frame walking, callerMember tricks, Reflection?, AST parsing?)
At instantiation, in a constructor, the stack trace does not contain information about which property/field it is about to be assigned to (if at all for that matter, it might just need to be instantiated, not assigned to anything). So there is no way to set such an id at constructor time.
Doing some magic in the Id property getter
There is no way to pass in parameters to a property getter, so we run into the same type of problem as with option 1: the stack trace contains no useful information by the time the getter is accessed.
Make the Employee object know about Workshop
No, just no.
Some weird runtime/weaving magic to "calculate" these paths when they are accessed?
Maybe, but how much effort to put in and to what purpose?
Expression parsing in a separate method:
//Left out the non-compiling code.
public static void Main(string[] args)
{
var Workshop = new Workshop
{
WheelsGuy = new PartTimeEmployee(),
InteriorsGuy = new FullTimeEmployee()
};
Console.WriteLine(GetObjectAccessPath((_) => Workshop.WheelsGuy));
}
public static string GetObjectAccessPath(Expression<Func<Workshop, Employee>> member)
{
string body = member.Body.Reduce().ToString();
// the line below might take some tweaking depending on your needs
return body.Substring(body.IndexOf($"{nameof(Workshop)}"));
}
// Output: Workshop.WheelsGuy
Use Reflection in a separate method to "get" a list of properties that are of any type derived from Employee and based on that Generate a list of ids with something like properties.Select(p => $"Workshop_{p.Name}");
Most viable: Re-design the object model:
(This is my opinion, and the requirements of your project might be different. Even if I am speculating here, the same principles presented here would apply in many other ways).
Extract more abstractions, like Position, Role, and Schedule. Part-time would be a schedule. Wheels guy would be a role. Position would be "an employee that fulfills the role of wheels guy at a workshop." There might be more examples (pay by hour/week/month, tax exemption, etc.).
As a rule, holding too many concerns in one class is a code smell and will get you in trouble quick. You can choose to carve up the classes however you want, but for what you "seem" to want, this part is important: have a class that represents the relationship between employee and workshop.
For example, instead of the Workshop holding instances of Employees: the Position class would hold/know about an Employee, his Role, his Schedule, and the Workshop he works at. The Position's Id could then easily be Id => $"Workshop_{Role}"; or Id => $"{WorkShop}_{Role}", etc. As a bonus, you get the design bonus of the Workshop being free from knowing which types of employees it might hold.
In general, I'd suggest you look into SOLID principles, it's an eye opener.

Building Generic Apps - Allowing Customer-specific Options

I've built an open source application, and I'd be curious to know how others are handling customer-specific requests. It's important to me to keep the app simple; I'm not trying to make it all things for all people. Apps can get bloated, complex, and just about unusable that way. However, there are some customer-specific options that would be nice (it just wouldn't apply to all customers). For example...
Say we have a domain entity called Server. In the UI, we let a customer pick from a list of servers. For one company, it's helpful to filter the servers by location (US, Germany, France, etc...). It would be easy enough to add a server property like this:
public class Server
{
public Location Location { get; set; }
// other properties here
}
My concern is that Server could become bloated with properties over time. And even if I only add location, not all customers would care about that property.
One option is to allow for user-defined fields:
public class Server
{
public string UserField1 { get; set; }
public string UserField2 { get; set; }
public string UserField3 { get; set; }
// etc...
// other properties here
}
Is that the best way to handle this? I don't like the fact that type safety is gone by making everything a string. Are there other/better ways that people are handling issues like this? Is there even a design pattern for something like this?
In my opinion, a good design pattern for something like this is to use schemas at the database level and then basic inheritance at the class level.
CREATE TABLE dbo.A (
ColumnA INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
ColumnB VARCHAR(50),
ColumnC INT,
etc.
)
And now we have a client who needs some specific functionality, so let's create an extension to this table in a different schema:
CREATE TABLE CustomerA.A (
ColumnA INT NOT NULL PRIMARY KEY,
Location VARCHAR(50)
)
But now we have another client who needs to extend it differently:
CREATE TABLE CustomerB.B (
ColumnA INT NOT NULL PRIMARY KEY,
DataCenterID INT
)
Though the fields may not be relevant, you get the idea, and so now we need to build the customer specific domain models here:
public abstract class A
{
public int ColumnA { get; set; }
public string ColumnB { get; set; }
public int ColumnC { get; set; }
}
public class CustomerA_A : A
{
public string Location { get; set; }
}
public class CustomerB_A : A
{
public int DataCenterID { get; set; }
}
And so now when we need to build something for Customer A, we'll build their subclass, and for Customer B theirs, and so on.
Now, FYI, this is the beginnings of a very dynamic system. I say that because the piece that's missing, that's not yet dynamic, is the user-interface. There is a significant number of ways that can be accomplished, but way outside the scope of this question. That is something you'll have to consider. I say that because the way you manage the interface will determine how you even know to build which subclass.
I hope this has helped.
The usual approach early on is to use the config XML files for this sort of thing. But programming for client-specific needs requires a whole mindset around how you program. Refer to this answer to a similar question.
Of course it always depends on how much customization you want to allow. In our product we went as far as enabling users to completely defined their own entities with properties and relations among them. Basically, every EntityObject, as we call our entities, in the end consists of a value collection and a reference to a meta-model describing the values within them. We designed our own query language that allows us to query the database and use expressions that are translate-able to any target language (although we currently only do SQL and .net).
The game does not end there and you quickly find that things like validation rules, permissions, default values and so on become a must have. Of course all of this then requires UI support, at least for the execution of the meta-model.
So it really depends on the amount of adjustment a end-user should be able to perform. I'd guess that in most cases simple user fields, as you described, will be sufficient. In that case I would provide a single field and store JSON text within that. In the UI you can then provide at least a semi-decent UI allowing structure and extensibility.
Option 1: Say "no". :-)
And while I say that (half) jokingly, there is some truth to it. Too often, developers open themselves up to endless customization by allowing one or two custom features, setting the snowball in motion.
Of course, this has to be balanced, and it sounds like you may be doing this to an extent. But if you truly want to keep your app simple, then keep it simple and avoid adding customizations like this.
Option 2: Inheritance.
If you really need to add the customization, I would lean the way of building a base class with all "standard" options, and then building customer-specific classes containing customer-specific optimizations.
For example:
public class Server
{
// all standard properties here
}
Then for Joe's Pizza, you can have:
public class JoesPizzaServer : Server
{
public Location Location { get; set; }
}
The side-benefit to this is that it will allow you to base your presentation views off of the client-specific (or base) models.
For example, in MVC you could set up your view models like this, and then you could have specific views for each customer.
For example, Bob's Burgers would have its own view on the base model:
#model MyApp.Server
#* implement the base form *#
And Joe's Pizza's view would use the custom model:
#model MyApp.JoesPizza
#* implement the base form -- a partial view -- with addtional custom fields
MVC does a really good job of supporting this type of pattern. If you're not using MVC (maybe WPF or Web Forms), there are still ways to leverage partial "view" files for accomplishing something similar.
Of course, your database can (and probably should) support a similar inheritance model. Entity Framework even supports various inheritance models like this.
I may be wrong here, but it looks like you want to handle different versions of your software with the same code base. I can think of two approaches for this:
Actually define different versions for it and handle changes for each client. This won't give you problems from the domain-modeling point of view, but will require a supporting infrastructure, which will have to scale according to your client requirements. There are some related questions out there (e.g. this, this and this).
Handle this at the domain-model level, as a user-defined configuration. The advantage of this approach is that you don't have to incorporate multiple versions of your software, but this comes at the expense of making your model more generic and potentially more complex. Also your tests will surely have to be adapted to handle different scenarios. If you are going in that direction I would model an object representing the attribute (with a name and a value) and consider the Server class as having a collection of attributes. In that way your model still captures your requirements in an OO style.
HTH
I approach from Python that I think would work rather well hear is a dictionary. The key is your field name, the value is the, errrrr... value ;)
It'd be simple enough to represent in a database too.

C# parent/child data structure availability?

is this type of data structures available in c# or as a free class library somewhere?
I want a multiple parent, multiple child type of data structure such as:
public class Many2ManyNode
{
public List<Object> Parents;
public List<Object> Children;
}
Its like a tree structure but with multiple parents and multiple child.
I'll stand by my previous comments that it looks like you want a directed graph (depending on how you want to use this structure), but if you just wanted to make your code better reflect what you're asking for it would be:
public class Node
{
public List<Node> Parents;
public List<Node> Children;
}
I found this QuickGraph library which was both compiled for silverlight and .net3.5. It also contains AI algorithms and other advance searching.
I'm not aware of any data structure in the framework that does what you are after.
There is a nice MSDN post that covers implementing data structures that will give you what you want. See An Extensive Examination of Data Structures Using C# 2.0
In particular look at part 5 on graphs.
You could try this library. Not sure if that will help or not. Generally I've found that I could aggregate the available generic classes to build the data structures that I have needed. Although the applications I have been working on were not overly concerned with large structures or high search performance.

C# CSLA business object dilemma: read-only vs read/write

I'm part of a team tasked to revamping our old VB6 UI/COBOL database application to modern times. Before I was hired, the decision was made (largely on sales, I'm sure) to redo the UI before the database. So, now we're using WPF and MVVM to great effect, it's been amazing so far, especially using CSLA as our Model layer.
However, because our development is side-by-side with the next version of the old product, we're constrained a bit. We can't make any changes (or minimal changes) to the calls made to the COBOL database. This has been fine so far, albeit pining back to the glory days of SQL Server if you can believe it.
Where I've hit a particularly nasty roadblock regarding our BO design is in dealing with "light" business objects returned in lists and their "full" counterparts. Let me try and construct an example:
Let's say we have a person object in the DB with a bunch of fields. When we do a search on that table, we don't return all the fields, so we populate our lite object with these. These fields may or may not be a subset of the full person. We may have done a join or two to retrieve some other information specific to the search. But, if we want to edit our person object, we have to make another call to get the full version to populate the UI. This leaves us with two objects and attempting to juggle their state in 1 VM, all the while trying to keep the person list in sync on whatever parent object it sits after delete, edit, and add. Originally, I made our lite person object derive from ReadOnlyBase<>. But now that I'm dealing with the same list behavior you'd have with a list of full BOs except with half full, half lite, I'm thinking I should've just made both the lite and full versions derive from BusinessBase<> and simply made the lite version setter properties private.
Has anyone else out there come across and found a solution for this? After sleeping on it, I've come up with this potential solution. What if we wrap the full and lite version of our BO in another BO, like this:
public class PersonFull : BusinessBase<PersonFull>
{
...
}
public class PersonLite : BusinessBase<PersonLite>
{
...
}
public class Person : BusinessBase<Person>
{
public PersonFull PersonFull;
public PersonLite PersonLite;
}
public class PersonList : BusinessListBase<PersonList, Person>
{
}
Obviously everything would be CSLA registered properties and such, but for the sake of brevity they're fields there. In this case Person and PersonList would hold all the factory methods. After a search operation PersonList would be populated by Person objects whose PersonLite members were all populated and the PersonFull objects were all null. If we needed to get the full version, we simply tell the Person object to do so, and now we have our PersonFull object so we can populate the edit UI. If the Person object is to be deleted, we can easily do this with the CSLA delete procedures in place, while still maintaining the integrity of our lists across all the VMs that are listening to it.
So, I hope this made sense to everyone, and if anyone has a different solution they've successfully employed or criticism of this one, by all means!
Thanks!
(Reposted from: http://forums.lhotka.net/forums/thread/35576.aspx)
public class PersonLite : ReadOnlyBase<PersonLite>
{
public void Update(PersonFull person) { }
}
public class PersonFull : BusinessBase<PersonFull>
{
// blah blah
}
I would update the "lite" object with the changes made to the "full" object, and leave it as ReadOnlyBase. It's important to remember that the "ReadOnly" in ReadOnlyBase means an object that is only read from the database, and never saved to it. A less elegant, but more accurate name would be NotSavableBase, because such objects lack the DataPortal_XYZ machinery for anything but fetches. For obvious reasons, such objects usually have immutable properties, but they don't have to. ReadOnlyBase derives from Core.BindableBase and implements INotifyPropertyChanged, so changing the values of its properties will work just fine with binding.
When you save your "full" object, you pass the newly saved instance to the Update(PersonFull) method of the instance that sits in your list, and update the properties of the "lite" object from the "full" object.
I've used this technique many times and it works just fine.
If you look over Rocky's examples that come with the CSLA framework, you'll notice that he always separates the read only objects from the read/write objects. I think this is done for good reason, because the behaviors are going to be drastically different. Read only objects will be more performance based, their validation will be very different, and usually have less information altogether. The read/write objects will not be as perfomance based and rely heavily on validation, authorization, etc.
However, that leaves you with the dilemma you currently find yourself in. What I would do is overload the constructor of each class so you can pass them between each other and "copy" what you need out of each other.
Something like this:
public class PersonLite : BusinessBase<PersonLite>
{
public PersonLite(PersonFull fullPerson)
{
//copy from fullPerson's properties or whatever
}
}
public class PersonFull : BusinessBase<PersonFull>
{
public PersonFull(PersonLite litePerson)
{
//copy from litePerson's properties or whatever
}
}
You could do this with a factory pattern as well, which is Rocky's preference I believe.

Best way to get a list of differences between 2 of the same objects

I would like to generate a list of differences between 2 instances of the the same object. Object in question:
public class Step
{
[DataMember]
public StepInstanceInfo InstanceInfo { get; set; }
[DataMember]
public Collection<string> AdHocRules { get; set; }
[DataMember]
public Collection<StepDoc> StepDocs
{...}
[DataMember]
public Collection<StepUsers> StepUsers
{...}
}
What I would like to do is find an intelligent way to return an object that lists the differences between the two instances (for example, let me know that 2 specific StepDocs were added, 1 specific StepUser was removed, and one rule was changed from "Go" to "Stop"). I have been looking into using a MD5 hash, but I can't find any good examples of traversing an object like this and returning a manifest of the specific differences (not just indicating that they are different).
Additional Background: the reason that I need to do this is the API that I am supporting allows clients to SaveStep(Step step)...this works great for persisting the Step object to the db using entities and repositories. I need to raise specific events (like this user was added, etc) from this SaveStep method, though, in order to alert another system (workflow engine) that a specific element in the step has changed.
Thank you.
You'll need a separate object, like StepDiff with collections for removed and added items. The easiest way to do something like this is to copy the collections from each of the old and new objects, so that StepDiff has collectionOldStepDocs and collectionNewStepDocs.
Grab the shorter collection and iterate through it and see if each StepDoc exists in the other collection. If so, delete the StepDoc reference from both collections. Then when you're finished iterating, collectionOldStepDocs contains stepDocs that were deleted and collectionNewStepDocs contains the stepDocs that were added.
From there you should be able to build your manifest in whatever way necessary.
Implementing the IComparable interface in your object may provide you with the functionality you need. This will provide you a custom way to determine differences between objects without resorting to checksums which really won't help you track what the differences are in usable terms. Otherwise, there's no way to determine equality between two user objects in .NET that I know of. There are some decent examples of the usage of this interface in the help file for Visual Studio, or here. You might be able to glean some directives from the examples on clean ways to compare the properties and store the values in some usable manner for tracking purposes (perhaps a collection, or dictionary object?).
Hope this helps,
Greg

Categories