I must develop a simple web application to produce reports. I have a single table "contract" and i must return very simple aggregated values : number of documents produced in a time range, average number of pages for documents and so on . The table gets filled by a batch application, users will have roles that will allow them to see only a part of the reports (if they may be called so ).
My purpose is :
develop a class, which generates the so called reports, opened to future extension (adding new methods to generate new reports for different roles must be easy )
decouple the web graphic interface from the database access
I'm evaluating various patterns : decorator, visitor, ... but being the return data so simple i cannot evaluate which apply or even if its the case to use one. Moreover i must do it i less than 5 days. It can be done if i make a so called "smart gui" but as told at point 1, i don't want to get troubles when new roles or method will be added.
thank you for your answers.
I'm sorry, i realize i haven't provided too much infos. I live in a Dilbert world. at the moment i've got the following info : db will be oracle (the concrete db doesn't exist yet) , so no EF, maybe linqtodataset (but i'm new to linq). About new features of the application,due to pravious experiences, the only thing i wish is not to be obliged to propagate changes over the whole application, even if it's simple. that are the reasons i've thougth to design patterns (note i've said "if it's the case" in my question) .
I'll KISS it and then will refactor it if needed , as suggested by ladislav mrnka, but i still appreciate any suggestion on how to keep opened to extension the data gathering class
KISS - keep it simple and stupid. You have five days. Create working application and if you have time refactor it to some better solution.
The road to good code is not paved with design patterns.
Good code is code that is readable, maintainable, robust, compatible and future-proof.
Don’t get me wrong: Design patterns are a great thing because they help categorise, and thus teach, the experience that earlier generations of programmers have accrued. Each design pattern once solved a problem in a way that was not only novel and creative, but also good. The corrolary is not that a design pattern is necessarily good code when applied to any other problem.
Good code requires experience and insight. This includes experience with design patterns, and insight into their applicability and their downsides and pitfalls.
That said, my recommendation in your specific case is to learn about the recommended practice regarding web interfaces, database access, etc. Most C# programmers write web applications in ASP.NET; tend to use LINQ-to-Entities or LINQ-to-SQL for database access; and use Windows Forms or WPF for a desktop GUI. Each of these may or may not fulfill the requirements of your particular project. Only you can tell.
How about you use strategy pattern for the retrieving data? And use interfaces like following to keep it extendable at all times.
IReportFilter: Report filter/criteria set
IReportParams: Gets report parameters
IReportData: Gets the report data in a result set
IReportFormat: Report formatting
IReportRender: Renders the report
Just thinking out loud.
Related
I apologize in advance for the generic nature of my question, but I was unable to find any helpful advice from people trying to do the same thing as me on the web. Let me describe my scenario:
I am providing end users/designers of a website the ability to customize their views by storing the views (using Razor) in the database. I have all of this working, but my question is the following; From a security standpoint, how can I ensure and enforce that unwanted code doesn't get executed in the user-defined view? There are two basic approaches that I think will work conceptually, but am not sure which one is more possible or feasible.
Option 1: Create a validation method in the administration tool that allows the user to input the view code. This would need to either take a whitelist or blacklist approach to what is allowable or not.
Option 2: Prevent unwanted code from being able to execute when rendering of the view occurs.
As a quick example of something that would need to be blocked, we wouldn't want to allow access to read or write files, access any data access functions, or even access configuration settings, etc. in the web.config. There will likely be a decently-sized list of things that probably shouldn't be allowable, but I'll need to sit down and try to think of as many security-related concerns as possible.
My question then is, which method would be the best bet? Also, can any direction be provided on how to go about either? I thought I might be able to make trust-level based change which would be Option 2, but couldn't find any way to make that work in a per-view based manor (the administration code is allowed to execute whatever it wants). I'm thinking Option 1 will end up being the best bet and I'll have to check for the input of certain framework functions that shouldn't be allowed. Does anyone have any experience doing anything like what I'm trying to do? ANY feedback is much appreciated!
This would be extremely difficult.
You could run the the template through the Razor preprocessor, then use Roslyn (still in early beta) to parse the generated file and look through all method calls (or constructors) and return an error if it calls something you don't like.
I strongly recommend that you use a whitelist for that, since the .Net framework is big enough that you are bound to overlook something in a blacklist.
However, I would instead recommend that you not use Razor at all and instead use a templating engine that does not allow real C# code.
Looming on my (C# 4.0) project horizon is the introduction of a user-configuration feature, wherein my colleagues need to obtain the ability to configure our software or a pre-run basis so that it will perform its duties in whatever way is needed. Every run (they'll tend to be lengthy simulations) will have have its own configuration file.
In the main, they'll want to define "products", fairly complex beasts comprising run-time parameters, IOC-style information (lists of calculation classes required in a Strategy Pattern-like way) and more stuff besides. Values could be numbers (integer and floating-point), strings, dates and lists of these.
We know the content will change (new parameter names, for example) as new products are introduced or existing ones evolve.
Options I've looked at include, in descending order of (my estimate of) syntax-heaviness:
XML
YAML
JSON
a DomainSpecific Language?
Some app-specific text notation
I'm looking for examples of more-or-less similar things: file formats, discussions of pros and cons from a technical and/or user perspective.
(I expect that at some time in the future we'll consider introducing a graphic front-end for such exercises, but we'll need to be able to configure executions some time before then.)
EDIT/UPDATE: I'm not particularly concerned about ease of implementation from the technical perspective: I'm looking for something my (very smart, but not technically-oriented) users will best be able to use to minimize the difficulty of writing what may be a fairly complex configuration.
Maybe "configuration" is a bad choice of word - what if we called it "simulation definition file" and considered that each user will create many of these over time?
If all of this can be described in a regular, attribute oriented way, it sounds like XML would meet your needs. C# has fantastic XML handling features including built-in serializers and LINQ that can save a ton of code implementation time. Also, creating a forms based UI from a schema is very straight forward.
I would suggest sitting down and creating a pseudo-schema to see if this would handle your use cases to help decide if this approach would work for you.
For examples, take a look at one of the many plugin systems that are driven by XML. The first one I would recommend is Eclipse.
In C# easiest way is to use a Built In Class System.Configuration ,first you should add an Configuration File ,using Visual Studio ,than you can edit it's attributes . Here is a How To
I have researched for some time the Orchard CMS and I'm pleased with some of his futures but also I have some issues that I don't know how to deal with them:
All the items (content type) are linear and they don't support a tree like data structure
(Ex: books > titles > web-links)
One of the big problem (depending how you see things) is that the model and the view for the items are coupled (content part > driver with display / editor views)
So for a new page the model, view and position are locked and you can have only one view of the model.
Use of advance language futures the are not suited for beginner developers and are not very clear (dynamic functions, clay objects - nice future, ...)
// Creating table VPlayerRecord
SchemaBuilder.CreateTable("VPlayerRecord", table => table
.ContentPartRecord()
.Column("Title", DbType.String)
.Column("VideoUrl", DbType.String)
.Column("WidthPx", DbType.Double)
.Column("HeightPx", DbType.Double)
);
This syntax is not very clear for beginner developers and is a bit over engineered. Also because the model is a dynamic object in the view we don't have any intellisense support.
To build a new page we have something like three degree of separation (3 projects)
Build a content part module
Build a content type
Build a theme module
How do you overcome these issues in your projects with Orchard CMS? and what other issues have you found and fixes :)
read this: http://orchardproject.net/docs/Creating-1-n-and-n-n-relations.ashx and this: http://orchardproject.net/docs/Creating-lists.ashx
How is this a problem and why do you see this as coupling? What alternative do you see?
Where do you see this as a problem and how has it blocked you?
edit on 2: it is not true that you can have only one view of the model. You can have any number of display types. For example, the summary view of items is handled this way. You also have display types for admin views, and you can add your own.
Not sure what you mean by "position is locked". If we mean the same thing by position, I'm puzzled by how you could have gotten such an idea. Relative positioning of parts and fields can be changed through placement.info.
edit on 3: even with this example, I'm not sure what would be difficult here. This is fairly expressive imo. Were you confused yourself or are you just assuming people would be?
You are claiming that this is over-engineered. How would you simplify it then? What feature do you think is not needed?
You don't get IntelliSense in views on model objects but the flexibility you gain by doing so justifies it by a very large margin. Ask anyone who's been making real use of it.
new 4th point: I can't see a reason why you would separate that into three modules or why you think you should. I've certainly never seen an example of that. I would also point out that creating a part and a type are often done by two different people (a type creator is often just a consumer of existing parts). But again you don't have to separate them into different modules.
A theme is clearly a different concern from the two others and makes sense to be a separate project but a theme can come with code and can actually in principle do everything a module is doing. So if you want to package a part, type and theme into a single package, you could do that. It wouldn't make a lot of sense but you could.
Finally, I don't see how any of those four points are related to page creation.
Orchard has to be taken as a challenge. As a beginner I have quickly built a few sites with ease. After that the learning curve became steeper. I've read many articles on the subject, numerous times.
I have used some CMS's before and had some knowledge what is the nature of managing content. Learning Orchard opened a whole new definition of content management. Now I can think of solving some everyday tasks and various business processes by implementing Orchard.
The whole thing is built in a very abstract layer, forcing you to think abstract too. If you follow this way, there are many blog posts, as well as official documentation to help you.
There are few basic building blocks and concepts that can be used like a bricks. Sounds like a phrase, I've heard it hunderts of times. I have also seen thousands of houses built from red square bricks, and they were all different, while the bricks were all equal. Such things can be accomplished with Orchard.
Read and understand the programming patterns. They are essential part of knowledge that will help you in solving Orchard based tasks. They will also help you change the way you are accomplishing your non Orchard related tasks.
I would say, there are two basic areas one need to understand. Storing and retreiving the piece of content is one, while presenting it to the crowd is the other. It might look difficult, it is difficult, but the goodies behind are delightfull. Not to mention great guys, some from evil empire, some not, that will certainly help you along the way. Not to forget, git's are your best friend. There are many wheels already invented. Caution, neither comes with free lunch.
P.S. I haven't write such a long post since usenet times. It might not be suitable for a site like this. It's kind a way to give a thanks to this French guy, and to all other Orchard evangelists from Poland, over Cyprus to the States. They saved my ass in many occasions.
First, I apologize if this is not an appropriate venue to ask this question, but I wasn't really sure where else to get input from.
I have created an early version of a .NET object persistence library. Its features are:
A very simple interface for persistence of POCOs.
The main thing: support for just about every conceivable storage medium. This would be everything from plain text files on the local filesystem, to embedded systems like SQLite, any standard SQL server (MySQL, postgres, Oracle, SQL Server, whatever), to various NoSQL databases (Mongo, Couch, Redis, whatever). Drivers could be written for nearly anything, so for instance you could fairly easily write a driver where the actual backing store could be a web-service.
When I first had this idea I was convinced it was totally awesome. I quickly created an initial prototype. Now, I'm at the 'hard part' where I am debating issues like connection pooling, thread safety, and debating whether to try to support IQueryable for LINQ, etc. And I'm taking a harder look at whether it is worthwhile to develop this library beyond my own requirements for it.
Here is a basic example of usage:
var to1 = new TestObject { id = "fignewton", number = 100, FruitType = FruitType.Apple };
ObjectStore db = new SQLiteObjectStore("d:/objstore.sqlite");
db.Write(to1);
var readback = db.Read<TestObject>("fignewton");
var readmultiple = db.ReadObjects<TestObject>(collectionOfKeys);
The querying interface that works right now looks like:
var appleQuery = new Query<TestObject>().Eq("FruitType", FruitType.Apple).Gt("number",50);
var results = db.Find<TestObject>(appleQuery);
I am also working on an alternative query interface that lets you just pass in something very like a SQL WHERE clause. And obviously, in the NET world it would be great to support IQueryable / expression trees.
Because the library supports many storage mediums with disparate capabilities, it uses attributes to help the system make the best use of each driver.
[TableName("AttributeTest")]
[CompositeIndex("AutoProperty","CreatedOn")]
public class ComplexTypesObject
{
[Id]
public string id;
[QueryableIndexed]
public FruitType FruitType;
public SimpleTypesObject EmbeddedObject;
public string[] Array;
public int AutoProperty { get; set; }
public DateTime CreatedOn = DateTime.Now;
}
All of the attributes are optional, and are basically all about performance. In a simple case you don't need any of them.
In a SQL environment, the system will by default take care of creating tables and indexes for you, though there is a DbaSafe option that will prevent the system from executing DDLs.
It is also fun to be able to migrate your data from, say, a SQL engine to MongoDB in one line of code. Or to a zip file. And back again.
OK, The Question:
The root question is "Is this useful?" Is it worth taking the time to really polish, make thread-safe or connection pooled, write a better query interface, and upload somewhere?
Is there another library already out there that already does something like this, NAMELY, providing a single interface that works across multiple data sources (beyond just different varieties of SQL)?
Is it solving a problem that needs to be solved, or has someone else already solved it better?
If I proceed, how do you go about trying to make your project visible?
Obviously this isn't a replacement for ORMs (and it can co-exist with ORMs, and coexist with your traditional SQL server). I guess its main use cases are for simple persistence where an ORM is overkill, or for NoSQL type scenarios and where a document-store type interface is preferable.
My advice: Write it for your own requirements and then open-source it. You'll soon find out if there's a market for it. And, as a bonus, you'll find that other people will tell you which bits need polishing; there's a very high chance they'll polish it for you.
Ben, I think it's awesome. At the very least post it to CodePlex and share with the rest of the world. I'm quite sure there are developers out there who can use an object persistence framework (or help polish it up).
For what its worth I think its a great idea.
But more importantly, you've chosen a project (in my opinion) that will undoubtedly improve your code construction and design chops. It is often quite difficult to find projects that both add value while improving your skills.
At least complete it to your initial requirents and then open source it. Anything after that it is a bonus!
While I think the idea is intriguing, and could be useful, I am not sure what long-term value it may hold. Given the considerable advances with EF v4 recently, including things like Code-Only, true POCO support, etc. achieving what you are talking about is actually not that difficult with EF. I am a true believer in Code-Only these days, as it is simple, powerful, and best of all, compile-time checked.
The idea about supporting any kind of data store is intriguing, and something that is worth looking into. However, I think it might be more useful, and reach a considerably broader audience, if you implemented store providers for EF v4, rather than trying to reinvent the wheel that Microsoft has now spent years on. Small projects more often than not grow...and things like pooling, thread safety, LINQ/IQueryable support, etc. become more important...little by little, over time.
By developing EF data store providers for things like SqLite, MongoDB, Xml files or flat files, etc. you add to the capabilities of an existing, familiar, accessible framework, without requiring people to learn an additional one.
The project I'm working on has just hit 4200 lines in the main C# file, which is causing IntelliSense to take a few seconds (sometimes up to 6 or so) to respond, during which Visual Studio locks up. I'm wondering how everyone else splits their files and whether there's a consensus.
I tried to look for some guides and found Google's C++ guide, but I couldn't see anything about semantics such as function sizes and file sizes; maybe it's there - I haven't looked at it for a while.
So how do you split your files? Do you group your methods by the functions they serve? By types (event handlers, private/public)? And at what size limit do you split functions?
To clarify, the application in question handles data - so its interface is a big-ass grid, and everything revolves around the grid. It has a few dialogs forms for management, but it's all about the data. The reason why it's so big is that there is a lot of error checking, event handling, and also the grid set up as master-detail with three more grids for each row (but these load on master row expanded). I hope this helps to clarify what I'm on about.
I think your problem is summed up with the term you use: "Main C# file".
Unless you mean main (as in the method main()) there is no place for that concept.
If you have a catch-all utility class or other common methods you should break them into similar functional parts.
Typically my files are just one-to-one mappings of classes.
Sometimes classes that are very related are in the same file.
If your file is too large it is an indication your class is too big and too general.
I try to keep my methods to half a screen or less. (When it is code I write from scratch it is usually 12 lines or fewer, but lately I have been working in existing code from other developers and having to refactor 100 line functions...)
Sometimes it is a screen, but that is getting very large.
EDIT:
To address your size limit question about functions - for me it is less about size (though that is a good indicator of a problem) and more about doing only one thing and keeping each one SIMPLE.
In the classic book "Structured Programming" Dijkstra once wrote a section entitled: "On our inability to do much." His point was simple. Humans aren't very smart. We can't juggle more than a few concepts in our minds at one time.
It is very important to keep your classes and methods small. When a method gets above a dozen lines or so, it should be broken apart. When a class gets above a couple of hundred lines, it should be broken apart. This is the only way to keep code well organized and manageable. I've been programming for nearly 40 years, and with every year that has gone by, I realize just how important the word "small" is when writing software.
As to how you do this, this is a very large topic that has been written about many different times. It's all about dependency management, information hiding, and object-oriented design in general. Here is a reading list.
Clean Code
SOLID
Agile Principles, Patterns, and Pratices in C#
Split your types where it's natural to split them - but watch out for types that are doing too much. At about 500 lines (of Java or C#) I get concerned. At about 1000 lines I start looking hard at whether the type should be split up... but sometimes it just can't/shouldn't be.
As for methods: I don't like it when I can't see the whole method on the screen at a time. Obviously that depends on size of monitor etc, but it's a reasonable rule of thumb. I prefer them to be shorter though. Again, there are exceptions - some logic is really hard to disentangle, particularly if there are lots of local variables which don't naturally want to be encapsulated together.
Sometimes it makes sense for a single type to have a lot of methods - such as System.Linq.Enumerable but partial classes can help in such cases, if you can break the type up into logical groups (in the case of Enumerable, grouping by aggregation / set operations / filtering etc would seem natural). Such cases are rare in my experience though.
Martin Fowler's book Refactoring I think gives you a good starting point for this. It instructs on how to identify "code smells" and how to refactor your code to fix these "smells." The natural result (although it's not the primary goal) is that you end up with smaller more maintainable classes.
EDIT
In light of your edit, I have always insisted that good coding practice for back-end code is the same in the presentation tier. Some very useful patterns to consider for UI refactorings are Command, Strategy, Specification, and State.
In brief, your view should only have code in it to handle events and assign values. All logic should be separated into another class. Once you do this, you'll find that it becomes more obvious where you can refactor. Grids make this a little more difficult because they make it too easy to split your presentation state between the presentation logic and the view, but with some work, you can put in indirection to minimize the pain caused by this.
Don't code procedurally, and you won't end up with 4,200 lines in one file.
In C# it's a good idea to adhere to some SOLID object-oriented design principles. Every class should have one and only one reason to change. The main method should simply launch the starting point for the application (and configure your dependency injection container, if you're using something like StructureMap).
I generally don't have files with more than 200 lines of code, and I prefer them if they're under 100.
There are no hard and fast rules, but there's a general agreement that more, shorter functions are better than a single big function, and more smaller classes are better than 1 big class.
Functions bigger than 40 lines or so should make you consider how you can break it up. Especially look at nested loops, which are confusing and often easy to translate to function calls with nice descriptive names.
I break up classes when I feel like they do more than 1 thing, like mix presentation and logic. A big class is less of a problem than a big method, as long as the class does 1 thing.
The consensus in style guides I've seen is to group methods by access, with constructors and public methods on the top. Anything consistent is great.
You should read up on C# style and refactoring to really understand the issues you're addressing.
Refactoring is an excellent book that has tips for rewriting code so that behavior is preserved but the code is more clear and easier to work with.
Elements of C# Style is a good dead tree C# style guide, and this blog post has a number of links to good online style guides.
Finally, consider using FxCop and StyleCop. These won't help with the questions you asked, but can detect other stylistic issues with your code. Since you've dipped your toe in the water you might as well jump in.
That's a lot, but developing taste, style and clarity is a major difference between good developers and bad ones.
Each class should do one small thing and do it well. Is your class a Form? Then it should not have ANY business logic in it.
Does it represent a single concept, like a user or a state? Then it shouldn't have any drawing, load/save, etc...
Every programmer goes through stages and levels. You're recognizing a problem with your current level and you are ready to approach the next.
From what you said, it sounds like your current level is "Solving a problem", most likely using procedural code, and you need to start to look more at new ways to approach it.
I recommend looking into how to really do OO design. There are many theories that you've probably heard that don't make sense. The reason they don't is that they don't apply to the way you are currently programming.
Lemme find a good post... Look through these to start:
how-do-i-break-my-procedural-coding-habits
are-there-any-rules-for-oop
object-oriented-best-practices-inheritance-v-composition-v-interfaces
There are also posts that will refer you to good OO design books. A "Refactoring" book is probably one of the very best places you could start.
You're at a good point right now, but you wouldn't believe how far you have to go. I hope you're excited about it because some of this stuff in your near future is some of the best programming "Learning Experiences" you'll ever have.
Good luck.
You can look for small things to change and change each slowly over time.
Are all the methods used in that class only? Look for support methods, such as validation, string manipulation, that can be moved out into helper/util classes.
Are you using any #region sections? Logical groupings of related methods in a #region often lend themselves to being split into separate classes.
Is the class a form? Consider using User Controls for form controls or groups of form controls.
Sometimes large classes evolve over time due to lots of developers doing quick fixes / new features without considering the overall design. Revisit some of the design theory links others have provided here and consider on-going support to enforce these such as code reviews and team workshops to review design.
Well, I'm afraid to say that you may have a bigger issue at hand than a slow load time. You're going to hit issues of tightly coupled code and maintainability/readability problems.
There are very good reasons to split class files into smaller files (and equally good reasons to move files to different projects/assemblies).
Think about what the purpose that your class is supposed to achieve. Each file should really only have a single purpose. If it's too generalized in its goal, for example, "Contain Shopping Basket Logic", then you're headed down the wrong path.
Also, as mentioned, the term you use: "Main C# file" just reeks that you have a very procedural mindset. My advise would be to stop, step back, and have a quick read up on some of the following topics:
General OOP principles
Domain-driven design
Unit testing
IoC Containers
Good luck with your searches.
Use Partial classes. You can basically break a single class into multiple files.
Perhaps the OP can respond: is your project using Object-Oriented Programming? The fact that you use the word "file" suggests that it is not.
Until you understand object orientation, there is no hope for improving your code in any important way. You'd do better to not split up the file at all, wait until it grows to be unbearably slow and buggy, then instead of bearing it any more, go learn OO.
The Intellisense parser in Visual Studio 2008 seems to be considerably faster than the one 2005 (I know they specifically did a lot of work in this area), so although you should definitely look into splitting the file up at some point as others have mentioned, Visual Studio 2008 may resolve your immediate performance problem. I've used it to open a 100K+ line Linq to SQL file without much issue.
Split the code so that each class/file/function/etc. does only One Thing™. The Single Responsibility Principle is a good guideline for splitting functionality into classes.
Nowadays, the largest classes that I write are about 200 lines long, and the methods are mostly 1-10 lines long.
If you have regions of code within a class, a simple method is to use the partial keyword and breakout that definition of the class into that file. I typically do this for large classes.
The convention I use is to have the ClassName_RegionName.cs. For example, if I want to break out a class that manages the schema for a database connection, and I called the class DatabaseConnection I would create a file called DatabaseConnection.cs for the main class and then DatabaseConnection_Schema.cs for the schema functionality.
Some classes just have to be large. That's not bad design; they are just implementation-heavy.