Delphi 8 introduced Class Helpers for the purposes of mapping the VCL/RTL to the .NET object hierarchy. They allow injecting methods into an existing class without overriding the the class or modifying the original. Later versions of Delphi found class helpers improved and they were ported to Win32.
In the help it says "they should not be viewed as a design tool to be used when developing new code."
Class Helpers violate traditional OOP, but I don't think that makes them a bad thing. Is this warning warranted?
Should class helpers be used when developing new code?
Do you use them when developing new code?
Why or why not?
Per Malcolm's comments: New code means daily application development, where you have some 3rd party libraries, some existing code, and then code you are writing.
Depends what you mean by "new code".
They aren't really relevant for classes you are newly developing, so in that case, no, they probably shouldn't be used.
But even in a brand new project, you may still need to modify an existing class that you can't change in other ways (vcl class, third-party class, etc). In this case, sure, I'd say go ahead.
They're not evil in and of themselves. Like most other things, you just need to understand how they work and use them in an appropriate context.
Before embracing class helpers as a new tool for fancy code, I think you have to understand the limitations is includes. There is only possible to provide one class helper for one class. So what will happen if you provide class helpers for your classes, and your classes derives from a common class that some other have provided a class helper for?
CodeGear introduces class helpers as 'a hack' to prevent breaking things, not as a cool design feature. When you design code, design it without class helpers. I know you can. When dealing with existing code that you can control, use refactoring. When there is no other way, reach for class helpers.
Thats my opinion any way...
Microsoft based LINQ heavily around their Extension Methods. In that light you should use Class Helpers in new code if that improves your code. See What are good uses for class helpers? for some good uses.
I use them a lot. I use Remote Objects and the objects there are created by the RO engine so you cannot add to them without descending from them and then other bits of messing around. Class Helpers mean I can treat them like any other object. and while a class can only have one helper, you can descend helper classes so you get the inherited behaviour.
Sorry, can't help but be Captain Obvious for a moment: If the internal Delphi people themselves state "they should not be viewed as a design tool to be used when developing new code" then by definition they shouldn't be used. They are there for extending the VCL for their own purposes only. Who else is going to give you a better reason than the people that wrote it?
I agree with Vegar in this: class helpers as a emergency tool. When you know they are the only way to get things done in the time provided. Later, if there's time to it, remove them.
I one time forgot a parametrization thing, and if class helpers didn't exist in Delphi 2006 it would cost A ENORMOUS LOT OF TIME..... With class helpers, it took 6 hours to make thigs work right. BUT, it was an emergency situation - class helpers are an obscure language feature and it create difficulties to new developers to follow the flow of the program.
Maybe a good aproach you can use is (as I use it):
Always give preference to inheritance over class helpers, use them only when inheritance is not an option.
Give preference to Class helpers over bare global methods.
If you're going to need the extendend functionality in more than a Unit, try something else (like class wrappers).
.Net Extensions methods are way too similar and where created and supported for the exactly same reason: Make an Extention of the base classes (rather than an upgrade wich in Delphi.Net was not an option in order to try to make Delphi native code kind of "compatible" with .Net code - IMHO this was too ambitious)
Anyway, Delphi Class helpers are still quite a tool in some situations.
These sound like C# extension methods. I would say that while extension methods like these are useful when you don't have the ability to modify a class that you need to extend with functionality, they are a poor way to design your own code. When designing your own code, you'd like all the functionality to be located in the same code file as much as possible rather than spread across different classes. I'd say use them for what they were intended for -- basically as decorators to add new functionality to closed classes -- and don't use them in designing your own code.
I find myself using them more and more as a design construct.
Situations in which I use them :
In a client/server setup, I extend shared base-classes with class helpers to provide server- or client-only functionality.
To complement VCL/RTL classes (and other third party code) with handy tooling functions.
To work around differences when classes don't share the same inheritance tree (using helpers makes it possible to have have generic Count and Items properties, for example).
In fact, I wish Delphi would accept multiple helpers for the same base class - I've even filed a request for this if I'm remembering correctly.
I found this article very interesting. It deals with C++ but the main ideas are language independent. The main gist is that global routines are sometimes preferrable to methods even in an OOP environment. From this view point, there's less need for class helpers.
Related
I want to use Zend Framework 2 to build an medium size website. So, I need the one place to store some global abstract classes, controller plug-ins, view helpers. For this purpose, I decided to utilize the Application module.
Is it good or bad? If bad, where should I put all common/abstract classes to be available for whole application?
Thanks!
It is OK to do so. However a better approach would be to separate into it's own Module. Something like Stdlib or Core. This one then you could simply copy-paste into all of your other projects.
Are there any classes (free, open source or commercial) that perform access control similar to what Java's AccessController does? I want to create a dynamic set of policies that can be changed at runtime.
But, I want to avoid having to code
if Allowed( ... ) then
all over the place. I know that I probably need to adjust my program class hierarchy, but I prefer that instead of manually adding guards all over the place.
If there are is no ready-to-use code, what would be a sensible approach? RTTI?
Edit: Here's an example from the Security Annotations and Authorization in GlassFish and the Java EE 5 SDK article. Since somebody mentioned annotations in a comment, I think this would be ideal:
#Stateless
#RolesAllowed("javaee")
public class HelloEJB implements Hello {
#PermitAll
public String hello(String msg) {
return "Hello, " + msg;
}
public String bye(String msg) {
return "Bye, " + msg;
}
}
From the article:
In this example, the hello() method is accessible by everyone, and the bye() method is accessible by users of role javaee.
Edit:
Well, it appears that the general consensus is that this can't be done in Delphi. Others think it is a bad approach.
Me, I still think this would be great. My experience with Annotations in Java (as a code monkey way down in the totem pole) is positive. You add a new method, you add some form of annotation (not exactly the same as Java Security Annotations) and you are done. An administrator can later go to the admin panel and add grant access to this new handler to a group or individual users. It just works.
These are my current alternatives:
The TMS Security System - this appears like a complete solution, with several tools. Worth looking into. I'm accepting this as an answer even if I'm probably not going for it.
This is something that looks promising: Delphi virtual method interception. It only works on virtual methods, but I don't think that's too difficult to comply. This and annotations could make an interesting system (it appears that this was originally designed for DataSnap authentication)
Having only one ActionManager in your application, and make sure that all actions can be only initiated from there. This way you can use the action manager OnExecute method; I pretend to use the TAction.Name property as the permission name ("handler"), reading a list of allowed actions from a table. I can use the action list from the action manager to display the whole list in the admin UI.
There is no such framework for Delphi yet, nor a concept like EJBs that would fit with it. DELPHI does support class annotations, and a framework like this could be designed, perhaps in conjunction with TAction, to provide security on an action level, but I doubt that this could be extended to blocking specific method calls. Delphi code does not ever ask permission to invoke a virtual method. Anything that injected itself into EVERY virtual method call in Delphi, adding a checkPermission call behind the scenes would (in my opinion) be evil. It would be Slow, and worse than writing such checks in by hand.
However, the same techniques that are used to Mock delphi classes could perhaps be used to create some auto-security wrapper object in the future.
I am guessing that the if the Java library in question used Aspects (essentially "injection" implemented via a technique like code-hooking) then it would not require "CheckAllowed" calls everywhere. If you didn't mind changing all your method invocations to implementing an interface, and then providing a wrapper that did the method invocations, and used some kind of auto-generated mock-security-wrapper around it, you could avoid calls to CheckAllowed.
So a guarded No, with a "limited framework possible in future" clause.
Yes, there is a Delphi Access Control Library (lkacl) (OpenSource), JCL (OpenSource) which offers a pretty comprehensive security features, and finally if your demands would be really high the most popular commercial solution is TMS Security System.
I asked this question over on the asp.net forums, and nobody seems to know what i'm talking about. I'm not sure why that is, but I figured I'll ask here to see if there is anyone with some insight.
Back when MVC2 was released, it included a sample AccountController that wrapped the built-in Membership and FormsAuthentication classes with testable interfaces and services. I read a lot about this, and it was considered a good thing because the Membership and FormsAuthentication classes were not easily testable.
Recently, I generated a new sample project with my up to date (SP1, MVC3, Tools Update, etc..) environment and I find that the AccountController is now much simpler. Gone are the Interfaces and MembershipService and FormsAuthenticationServices. The sample now calls the Membership and FormsAuthentication classes directly.
I'm wondering if anyone knows when this happened and why? Are the testable interfaces no longer considered correct? Was there a technical reason to change this?
The best I can figure is that this happened as a part of the change to remove a possible vulnerability when passing return url's on the open url.
Any insight?
The new model resembles EF's code first approach where the AccountModel is a POCO class. Inside the new API there are no longer abstractions but direct calls to static methods such as FormsAuthentication.SetAuthCookie making this code difficult to unit test. Not something I would recommend basing your real world application code upon.
And, yes, they have fixed a vulnerability inside the LogOn method which was not verifying if the return url is a relative url before redirecting.
Personally I would recommend you using abstractions in order to weaken the coupling between your controller logic and its dependencies. This will make the code easier to unit test.
For me passing all those domain models to views without using view models are total anti-patterns and I have never bothered with them. I simply create an empty project and do the things my way. I mean in the default project they even use ViewBag for Christ sake!
The Account Controller was changed with the MVC3 tools update (When they also included the use of jQuery via Nuget)
I'm working on a small library for for ASP.NET MVC 3 that should offer better reusability of model metadata and easy mapping from data entities from / to custom viewmodels. For this I need to be able to provide my own implementation of ICustomTypeDescriptor for three different areas of interest in ASP.NET MVC:
Scaffolding
Validation
Modelbinding
It seems like this could be done by setting System.Web.Mvc.ModelMetadataProviders.Current to my own CustomMetaDataProvider, but this is not nearly enough to cover all three points above.
The problem is that there are several classes in System.Web.Mvc which call directly into this System.Web.TypeDescriptorHelper which is not extensible because it looks like this:
internal static class TypeDescriptorHelper {
public static ICustomTypeDescriptor Get(Type type) {
return new AssociatedMetadataTypeTypeDescriptionProvider(type).GetTypeDescriptor(type);
}
}
The only solution I found is very awkward and required subclassing lots of types from System.Web.Mvc to make it work. I even had to re-implement CustomModelBinderDictionary completely only to overwrite one or two lines of code. So it works, but it is a very messy hack and likely to break the next time I update to a new ASP.NET MVC version.
So here's what I like to know : Did I miss any simple way to do this?
Bonus question: If not and you are from the MVC team, could you consider creating an appropriate extensibility point in MVC 4 ;-)?
Edit: In reply to the question why I need to code my own TypeDescriptor: There are several reasons for this:
1. Most important: I need a workaround for the problem described at https://forums.asp.net/t/1614439.aspx/1
2. Also, I need to insert metadata dynamically for various reasons. For example I want to code my own Bind attribute, but BindAttribute is sealed. So instead of deriving from it, I am emitting a matching BindAttribute dynamically from the TypeDescriptor when detecting my own bind attribute implementation.
According to Brad Wilson (an ASP.NET MVC team member) this issue has been put on the bug list for MVC 4. So it seems there is no good solution for the moment, but hopefully this will be solved when MVC 4 comes out.
For anyone interested in my library for reusable validation and scaffolding metadata and model / viewmodel mapping, feel free to subscribe my blog at https://devermind.wordpress.com/. I'm going to release the library there.
I'm not sure what it is that you're trying to do with custom implementations of Validation, ModelBinding and potentially ModelMetadata, that can't be done with the DependencyResolver functionality in MVC?
The new scaffolding support in the recent Tooling Update for MVC 3 may meet your needs for scaffolding; however I would take a look at possibly hooking into the DependencyResolver functionality for the ModelBinding, ModelMetadata and Validation and see if they can achieve what you are looking for. I had a similar situation recently where I needed to implement a lot of these behaviors from scratch to provide a flexible framework, and I was able to do so with just ModelMetadata and Validation providers using IoC. I also ended up inheriting DynamicObject (or ExpandoObject) in a few cases to give even more flexibility. I know this isn't exactly a direct answer but I'm not sure why you would need access to anything lower than these extensability points?
EDIT: If you're looking to reuse ModelMetadata on similar ViewModels to avoid having to redefine the same ModelMetadata over in multiple places, you might want to consider the implications of this. There are many times when you want certain data restrictions on your entities but these restrictions should be on the DataModel and not the ViewModel. The user may have a slightly more restrictive rules. For example, you may stipulate that certain fields are readonly for the user in the ViewModel, but that the entity used as a DataModel does allow you to modify the value (typically from within your code). Similarly you may run into situations where the ModelMetadata used to generate the Create view for the VideModel might be slightly different than the ViewModel used for the Edit view. Reusing them may seem like a great way to stay consistent and reduce code duplication but it may be something you regret later on. I recently ran into the same issue where I wanted to avoid writing a new ViewModel for each view that may cause a postback, I haven't found a perfect solution I like but I think reusing the ModelMetadata will cause more problems that it might solve in my opinion. Writing ViewModels for views that need them will also probably eliminate your need to implement a custom BindAttribute implementation and the Scaffolding issue.
If I'm right in assuming not wanting to create so many ViewModels with their own Metadata is what's causing you to try and find implementations of a custom BindAttribute, custom Scaffolding, custom ModelMetadata, custom Validation and custom ModelBinding... it may be worth looking at how much time it would actually take to just create the ViewModels.
If you find a better approach, feel free to let me know :-)
I recently started reading about ASP.net MVC and after getting excited about the concept, i started to migrate all my webform project to MVC but i am having a hard time keeping my controller skinny even after following all the good advices out there (or maybe i just don't get it ... ).
The website i deal with has Articles, Videos, Quotes ... and each of these entities have categories, comments, images that can be associated with it. I am using Linq to sql for database operations and for each of these Entities, i have a Repository, and for each repository, i create a service to be used in the controller.
so i have -
ArticleRepository
ArticleCategoryRepository
ArticleCommentRepository
and the corresponding service
ArticleService
ArticleCategoryService ...
you see the picture.
The problem i have is that i have one controller for article,category and comment because i thought that having ArticleController handle all of that might make sense, but now i have to pass all of the services needed to the Controller constructor. So i would like to know what it is that i am doing wrong. Are my services not designed properly? should i create Bigger service to encapsulate smaller services and use them in my controller? or should i have an articleCategory Controller and an articleComment Controller?
A page viewed by the user is made of all of that, thee article to be viewed,the comments associated with it, a listing of the categories to witch it applies ... how can i efficiently break down the controller to keep it "skinny" and solve my headache?
Thank you!
I hope my question is not too long to be read ...
This is the side effect of following the Single Responsibility Pattern. If each class is designed for only one purpose, then you're going to end up with a lot of classes. This is a good thing. Don't be afraid of it. It will make your life a lot easier in the long run when it comes to swapping out components as well as debugging which components of your system aren't working.
Personally, I prefer putting more of my domain logic in the actual domain entities (e.g. article.AddComment(comment) instead of articleCommentService.AddComment(article, comment)), but your approach is perfectly fine as well.
I think you are headed in the right direction. The question is how to instantiate your services? I'm no MVC.NET guru, but have done plenty of service oriented Java projects and exactly the pattern you are discussing.
In Java land we would usually use Spring to inject singleton beans.
1) You can do the same thing in .NET, using dependency injection frameworks.
2) You can instantiate services as needed in the method, if they are lightweight enough.
3) You can create static service members in each controller as long as you write them to be threadsafe, to reduce object churn. This is the approach I use in many cases.
4) You can even create a simple, global service factory that all controllers access, which could simply be a class of singletons.
Do some Googling on .NET dependency injection as well.