Doctrine 2 Value Objects - doctrine

I have been implementing value objects as custom DBAL types in Doctrine 2 and it's been working OK. However I have been wondering if this is the best way. I've thought about using the Post Load listener to instantiate the Value Objects. Also instantiating them through Entity accessors when requested, the advantage with the latter would be that I would not instantiate more objects than I need.
My question is: which method is best? Or is there a better way to do it? Are there any gotchas or unreasonable performance hits with the above?

IMHO, both approaches are equally valuable, while waiting for native support for value objects.
I personally favor the second approach (instantiating them through accessors when requested) for two reasons:
As you mentioned, it offers better performance as the conversion is only done when needed;
It decouples your application from Doctrine dependency: you're writing less code that is Doctrine-specific.
An example of this approach:
class User
{
protected $street;
protected $city;
protected $country;
public function setAddress(Address $address)
{
$this->street = $address->getStreet();
$this->city = $address->getCity();
$this->country = $address->getCountry();
}
public function getAddress()
{
return new Address(
$this->street,
$this->city,
$this->country
);
}
}
This code will be fairly easy to refactor when Doctrine will offer native VO support.
About custom mapping types, I do use them as well, for single-field VO (Decimal, Point, Polygon, ...) but would tend to reserve them for general-purpose, reusable types that can be used across multiple projects, not for project-specific single-field VO where I would favor the approach above.

Related

Yes or no: Should models in MVC contain application logic?

Yesterday I had some discussion with one of our developers regarding MVC, more precisely about the role of the model component in MVC.
In my opinion, a model should just contain properties and almost no functionality so there are as few methods in model classes as possible.
My collegue though believes that models could and should have more than that and offer a lot more functionality.
Here is an example we argued about.
Example 1
Let's say we wanted to create a blog. A blog has articles and tags. Each article can have multiple tags and each tag can belong to multiple articles. So we have a m:n relation here.
In pseudocode it'd probably look something like this:
class Article{
public int id;
public String title;
public String content;
public Tag[] tags;
// Constructor
public void Article(id, title, content, tags){
this.id = id;
this.title = title;
this.content = content;
this.tags = tags;
}
}
class Tag{
public int id;
public String name;
// Constructor
public Tag(id, name){
this.id = id;
this.name = name;
}
}
Now, assume that we're working loose coupled here which means that it could happen that we have an instance of Article which has no Tags yet so we'll use an Ajax call (to our backend which has a database containing all the information) to get the tags that belong to our article.
Here comes the tricky part. I believe that getting the backend data via Ajax+JSON should be the controller's job using a dedicated class which deals with the ajax request using a parser:
class MyController{
private void whatever(articleID){
Article article = (Article) ContentParser.get(articleID, ContentType.ARTICLE);
doSomethingWith(article);
}
}
public abstract class ContentParser{
public static Object get(int id, ContentType type){
String json = AjaxUtil.getContent(id, type.toString()); // Asks the backend to get the article via JSON
Article article = json2Article(json);
// Just in case
Tag[] tags = article.tags;
if (tags == null || tags.length <= 0){
json = AjaxUtil.getContent(article.id, ContentType.TAGS); // Gets all tags for this article from backend via ajax
tags = json2Tags(json);
article.tags = tags;
}
return article;
}
// Does funky magic and parses the JSON string. Then creates a new instance of Article
public static Article json2Article(String json){
/*
...
*/
return new Article(id, title, content, tags);
}
// Does funky magic and parses the JSON string. Then creates a new instance of Tag
public static Tag[] json2Tags(String json){
/*
...
*/
return tags;
}
}
Example 2
My collegue believes that this breaks with the idea of MVC, he suggests that the model should take care about this:
class Blog{
public int id;
public String title;
public Article[] articles;
// Constructor
public Blog(id, title, articles){
this.id = id;
this.title = title;
this.articles = articles;
}
public void getArticles(){
if (articles == null || articles.length <= 0){
String json = AjaxUtil.getContent(id, ContentType.ARTICLE); // Gets all articles for this blog from backend via ajax
articles = json2Articles(json);
}
return articles;
}
private Article[] json2Articles(String json){
/*
...
*/
return articles;
}
}
class Article{
public int id;
public String title;
public String content;
public Tag[] tags;
// Constructor
public Article(id, title, content, tags){
this.title = title;
this.content = content;
this.tags = tags;
}
public Tag[] getTags(){
if (tags == null || tags.length <= 0){
String json = AjaxUtil.getContent(id, ContentType.TAGS); // Gets all tags for this article from backend via ajax
tags = json2Tags;
}
return tags;
}
// Does funky magic and parses the JSON string. Then creates a new instance of Tag
private Tag[] json2Tags(String json){
/*
...
*/
return tags;
}
}
And outside of the model you'd do: blog.getArticles(); or article.getTags(); to get the tags without bothering with the ajax call.
However, as handy as this might be I believe that this approach breaks with MVC because at the end of the day all models will be full of methods that do various funky stuff and the controller and helper classes do almost nothing.
In my understanding of MVC, models should only contain properties and a minimum of "helper methods" inside. For example a model "Article" could offer a method getNumOfTags() but it shouldn't do any Ajax calls on its own.
So, which approach is correct?
Generally I try to keep controllers simple in terms of logic too. If business logic is required, it will go up to 'service layer' classes to handle it. This also saves repeating any code/logic too, which ultimately makes the whole project more maintainable if business logic was to change. I just keep models purely as entity objects.
I think the answer above sums it up nicely though, it is easy to over engineer a project based on design patterns: Go with whatever works for you and is most maintainable/efficient.
You should stop treating "model" in MVC like some class. Model is not a class or object. Model is a layer (in modern MVC, there has been some evolutions since the inception of concept). What people tend to call "models" are actually domain object (I blame Rails for this mass-stupidity).
The application logic (interaction between domain logic structures and storage abstraction) should be a part of model layer. To be more precise: it should be inside the Services.
The interaction between presentation layer (controllers, views, layouts, templates) and model layer should happen only through those services.
Application has no place in controllers. Controllers are structures of presentation layer, and they are responsible for handling user input. Please do not expoqbse deomain objects to it.
Correct? Either. They both compile, don't they?
Handy tricks are nice, why not use them were you can? That being said, as you've pointed out, you may get bloated models if you put all sorts of logic in them. Likewise, though, you can get bloated controllers when they do massive amounts in each action. There are ways to abstract elements out of either, if that's necessary too.
At the end of the day all design patterns are is guidelines. You shouldn't blindly follow any rule, just because someone else said it. Do what works for you, what you think gives clean, extensible code and hits whatever metrics you think make good code.
All that being said, for true idealistic MVC I would say that models should not have any external actions, they're data representations, nothing more. But feel free to disagree :-)
Your suggestion about the modules (without any business logic inside) sounds more like you talk about Value Objects. The suggestion of your college sounds more like Domain Objects.
In my opinion the concept which will be used depends on the framework which is used (that's the practical view, the more philosophical one is bellow). If framework is used it usually sets rules about how you should implement each component.
For example we can look at different MVC frameworks. In Flex's Cairngorm framework we have both. VO (Value objects) are primary used for bindings to the view, while the DO (Domain objects) hold the business logic. If we look at ASP.NET's MVC implementation there we have a model which contains at least the data (VO) but also some validation (if required). Let us look at a UI MV* framework - for example Backbone.js. Backbone's documentation says:
Models are the heart of any JavaScript application, containing the
interactive data as well as a large part of the logic surrounding it:
conversions, validations, computed properties, and access control.
If we look into the traditional MVC provided by Smalltalk we see that: "Model: manages the behavior and data of the application domain" so we have some behavior in it, not just plain data.
Let's think practically, if don't have any logic in the Model probably we should put all the application and business logic into the Controller.
Now let's focus on a concrete example. Imagine we have a model which is a Graph. We want to find the shortest path between two nodes in it. A good question is where to put the algorithm which finds the shortest path? It's a kind of business logic, right? If we look at the main benefits of MVC (code reuse, DRY etc.) we can see that if we want to reuse our model in the best possible way we should implement the shortest path inside it. The shortest path algorithm usually depends on the graph inner representation (or at least for best performance of the algorithm) but this representation is encapsulated into the model, unfortunately we cant reuse the full shortest path for matrix representation and list of neighbors so it's not a good idea to put it into the controller.
So as conclusion I can said that it depends on your needs (mostly). The traditional MVC purpose is to be used in the UI (inside GoF
The Model/View/Controller (MVC) triad of classes [first described by Krasner and Pope in >1988] is used to build user interfaces in Smalltalk-80.
)
now we use it in different areas - only UI, for web applications, etc. It cant be used in it's pure form because of that.
But anyway, in my opinion the best separation of concerns can be achieved by isolation of the business logic into the Model and the application logic into the Controller.
In short I believe the Model should just be data that will be sent to your View. It helps drive the MVC paradigm into other aspects of your application.
If you are tring not to break the MVC pattern your data should all be returned as a Business Model to your controller and unpacked into your ViewModel. Request the information server side and then send everything. If you need to make JSon requests then that should either be a Rest Service or calls to a Controller. Having these getTags and getArticles makes it very messy ... if your view is now deciding on which to call ... I cant understand why you dont have that information isnt available upfront. Using static methods is the same approach just a different angle.
I have found it best to have my controller actions call an injected service which does the magic and use the Models within the MVC web application to return the information. This makes things neater and further emphasisis the seperation of concern. Your Controller Actions then become very lean and its clear what they are doing.
I believe starting by treating the Model as completly dumb might go a long way in sorting some of these architectural problems I am seeing from this code.
Yes. It should. You are talking about Domain Driven Design.
https://en.wikipedia.org/wiki/Domain-driven_design
If you feel, you are not doing that then you are doing Anaemic Domain Model Design. that is an Anti Pattern.
I read through an article from Martin Flower on how bad the Anaemic Domain Design is. https://martinfowler.com/bliki/AnemicDomainModel.html

When creating a DAO, when should the backend connection occur?

I was thinking through some DAO design stuff with a teammate and came across an interesting question about which I have yet to find any best practices guidelines.
When creating a DAO object, when should the DB connection occur? We've talked through instantiating an object that creates a DB connection in a constructor (then uses it in subsequent methods) and making a static class that establishes a connection and tears it down after every method call.
Both have clear performance implications based on environment - a static object would be good for a few intermittent calls whereas instantiating an object that holds a connection would be great for a number of calls in a short amount of time for a small number of users.
Is there another way to do this? Perhaps something that would be better for performance across most situations?
Since you have tagged this as mvc, I will assume that your DAOs already exist within the model layer. As i understand it. the DAOs are responsible for for same task as Data Mappers, and provide the information from storage (which might or might not be SQL database) to your Domain Objects within the Model Layer.
The best way to deal with this issue would be to have factory, which create the data access objects within your model layer. This would have several advantages:
decoupling from the class names of different DAOs
ability to know when first DAO is initialized
sharing single DB connection between all DAO instances
This is how I would implement something like it:
class DaoFactory
{
protected $connection = null;
protected $provider = null;
public function __construct( $provider )
{
$this->provider = $provider;
}
public function create( $name )
{
if ( $connection === null )
{
$connection = call_user_func( $this->provider );
}
$instance = new $name;
$instance->setConnection( $connection );
return $instance
}
}
And the usage would look something like this:
$connectionProvider = function()
{
$instance = new \PDO('mysql:host=localhost;dbname=testdb;charset=utf8',
'username', 'password');
$instance->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
$instance->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false);
return $instance;
};
$daoFactory = new DaoFactory( $connectionProvider );
Then you pass the $daoFactory variable to whichever object will require to create DAO. This way, if need arises, you can easily replace the factory (as long as it implements same create() method footprint), with something completely different. And your domain business logic is in no way impacted by such a change.
The objects which use this factory became completely unaware that there even exists a database connection, and that DAOs need it to function. And you can even end up with situations, when you don't even need to establish a connection to database.
Rant Since you have data access objects on your codebase, it would indicate that you are trying to use OOP. Or at least something similar. But the static classes/functions/variables are not part of OOP paradigm. If you have a class with static-only methods and few static variables, what you have actually made are just simple php function with global variables, wrapped in a namespace, which just happens to look like class.
PHP community tends to call this COP (class oriented programming) as a joke, but essentially it is procedural code.

Can I include a convenience query in a Doctrine 2 Entity Method?

I'd like to include some additional functions in my Doctrine 2 entities to contain code that I'm going to have to run quite frequently. For example:
User - has many Posts
Post - has a single user
I already have a function $user->getPosts(), but this returns all of my posts. I'm looking to write a $user->getActivePosts(), which would be like:
$user->getPosts()->where('active = true') //if this were possible
or:
$em->getRepository('Posts')->findBy(array('user'=>$user,'active'=>true)) //if this were more convenient
As far as I can tell, there's no way to get back to the entity manager though the Entity itself, so my only option would be
class User {
function getActivePosts() {
$all_posts = $this->getPosts();
$active_posts = new ArrayCollection();
foreach ($all_posts as $post) {
if ($post->getActive()) {
$active_posts->add($post);
}
}
return $active_posts;
}
However, this requires me to load ALL posts into my entity manager, when I really only want a small subset of them, and it requires me to do filtering in PHP, when it would be much more appropriate to do so in the SQL layer. Is there any way to accomplish what I'm looking to do inside the Entity, or do I have to create code outside of it?
I think you should implement the method on the PostRepository rather than on the entity model.
I try to keep all model related logic in the repositories behind "domain specific" methods. That way if you change the way you represent whether a post is active or not, you only have to change the implementation of a single method instead of having to find all the active = true statements scattered around in your application or making changes in an "unrelated" entity model.
Something like this
PostRepository extends EntityRepository {
public function findActiveByUser($user){
// whatever it takes to get the active posts
}
}

Replace conditional with polymorphism - nice in theory but not practical

"Replace conditional with polymorphism" is elegant only when type of object you're doing switch/if statement for is already selected for you. As an example, I have a web application which reads a query string parameter called "action". Action can have "view", "edit", "sort", and etc. values. So how do I implement this with polymorphism? Well, I can create an abstract class called BaseAction, and derive ViewAction, EditAction, and SortAction from it. But don't I need a conditional to decided which flavor of type BaseAction to instantiate? I don't see how you can entirely replace conditionals with polymorphism. If anything, the conditionals are just getting pushed up to the top of the chain.
EDIT:
public abstract class BaseAction
{
public abstract void doSomething();
}
public class ViewAction : BaseAction
{
public override void doSomething() { // perform a view action here... }
}
public class EditAction : BaseAction
{
public override void doSomething() { // perform an edit action here... }
}
public class SortAction : BaseAction
{
public override void doSomething() { // perform a sort action here... }
}
string action = "view"; // suppose user can pass either "view", "edit", or "sort" strings to you.
BaseAction theAction = null;
switch (action)
{
case "view":
theAction = new ViewAction();
break;
case "edit":
theAction = new EditAction();
break;
case "sort":
theAction = new SortAction();
break;
}
theAction.doSomething(); // So I don't need conditionals here, but I still need it to decide which BaseAction type to instantiate first. There's no way to completely get rid of the conditionals.
You're right - "the conditionals are getting pushed up to the top of the chain" - but there's no "just" about it. It's very powerful. As #thkala says, you just make the choice once; from there on out, the object knows how to go about its business. The approach you describe - BaseAction, ViewAction, and the rest - is a good way to go about it. Try it out and see how much cleaner your code becomes.
When you've got one factory method that takes a string like "View" and returns an Action, and you call that, you have isolated your conditionality. That's great. And you can't properly appreciate the power 'til you've tried it - so give it a shot!
Even though the last answer was a year ago, I would like to make some reviews/comments on this topic.
Answers Review
I agree with #CarlManaster about coding the switch statement once to avoid all well known problems of dealing with duplicated code, in this case involving conditionals (some of them mentioned by #thkala).
I don't believe the approach proposed by #KonradSzałwiński or #AlexanderKogtenkov fits this scenario for two reasons:
First, from the problem you've described, you don't need to dynamically change the mapping between the name of an action and the instance of an action that handles it.
Notice these solutions allows doing that (by simply assigning an action name to a new action instance), while the static switch-based solution doesn't (the mappings are hardcoded).
Also, you'll still need a conditional to check if a given key is defined in the mapping table, if not an action should be taken (the default part of a switch statement).
Second, in this particular example, dictionaries are really hidden implementations of switch statement. Even more, it might be easier to read/understand the switch statement with the default clause than having to mentally execute the code that returns the handling object from the mapping table, including the handling of a not defined key.
There is a way you can get rid of all conditionals, including the switch statement:
Removing the switch statement (use no conditionals at all)
How to create the right action object from the action name?
I'll be language-agnostic so this answer doesn't get that long, but the trick is to realize classes are objects too.
If you've already defined a polimorphic hierarchy, it makes no sense to make reference to a concrete subclass of BaseAction: why not ask it to return the right instance handling an action by its name?
That is usually implemented by the same switch statement you had written (say, a factory method)... but what about this:
public class BaseAction {
//I'm using this notation to write a class method
public static handlingByName(anActionName) {
subclasses = this.concreteSubclasses()
handlingClass = subclasses.detect(x => x.handlesByName(anActionName));
return new handlingClass();
}
}
So, what is that method doing?
First, retrieves all concrete subclasses of this (which points to BaseAction). In your example you would get back a collection with ViewAction, EditAction and SortAction.
Notice that I said concrete subclasses, not all subclasses. If the hierarchy is deeper, concrete subclasses will always be the ones in the bottom of the hierarchy (leaf). That's because they are the only ones supposed not to be abstract and provide real implementation.
Second, get the first subclass that answer whether or not it can handle an action by its name (I'm using a lambda/closure flavored notation). A sample implementation of the handlesByName class method for ViewAction would look like:
public static class ViewAction {
public static bool handlesByName(anActionName) {
return anActionName == 'view'
}
}
Third, we send the message new to the class that handles the action, effectively creating an instance of it.
Of course, you have to deal with the case when none of the subclass handles the action by it's name. Many programming languages, including Smalltalk and Ruby, allows passing the detect method a second lambda/closure that will only get evaluated if none of the subclasses matches the criteria.
Also, you will have to deal with the case more than one subclass handles the action by its name (probably, one of these methods was coded in the wrong way).
Conclusion
One advantage of this approach is that new actions can be supported by writing (and not modifying) existing code: just create a new subclass of BaseAction and implementing the handlesByName class method correctly. It effectively supports adding a new feature by adding a new concept, without modifying the existing impementation. It is clear that, if the new feature requires a new polimorphic method to be added to the hierarchy, changes will be needed.
Also, you can provide the developers using your system feedback: "The action provided is not handled by any subclass of BaseAction, please create a new subclass and implement the abstract methods". For me, the fact that the model itself tells you what's wrong (instead of trying to execute mentally a look up table) adds value and clear directions about what has to be done.
Yes, this might sound over-design. Please keep an open mind and realize that whether a solution is over-designed or not has to do, among other things, with the development culture of the particular programming language you're using. For example, .NET guys probably won't be using it because the .NET doesn't allow you to treat classes as real objects, while in the other hand, that solution is used in Smalltalk/Ruby cultures.
Finally, use common sense and taste to determine beforehand if a particular technique really solves your problem before using it. It is tempting yes, but all trade-offs (culture, seniority of the developers, resistance to change, open mindness, etc) should be evaluated.
A few things to consider:
You only instantiate each object once. Once you do that, no more conditionals should be needed regarding its type.
Even in one-time instances, how many conditionals would you get rid of, if you used sub-classes? Code using conditionals like this is quite prone to being full of the exact same conditional again and again and again...
What happens when you need a foo Action value in the future? How many places will you have to modify?
What if you need a bar that is only slightly different than foo? With classes, you just inherit BarAction from FooAction, overriding the one thing that you need to change.
In the long run object oriented code is generally easier to maintain than procedural code - the gurus won't have an issue with either, but for the rest of us there is a difference.
Your example does not require polymorphism, and it may not be advised. The original idea of replacing conditional logic with polymorphic dispatch is sound though.
Here's the difference: in your example you have a small fixed (and predetermined) set of actions. Furthermore the actions are not strongly related in the sense that 'sort' and 'edit' actions have little in common. Polymorphism is over-architecting your solution.
On the other hand, if you have lots of objects with specialised behaviour for a common notion, polymorphism is exactly what you want. For example, in a game there may be many objects that the player can 'activate', but each responds differently. You could implement this with complex conditions (or more likely a switch statement), but polymorphism would be better. Polymorphism allows you to introduce new objects and behaviours that were not part of your original design (but fit within its ethos).
In your example, in would still be a good idea to abstract over the objects that support the view/edit/sort actions, but perhaps not abstract these actions themselves. Here's a test: would you ever want to put those actions in a collection? Probably not, but you might have a list of the objects that support them.
There are several ways to translate an input string to an object of a given type and a conditional is definitely one of them. Depending on the implementation language it might also be possible to use a switch statement that allows to specify expected strings as indexes and create or fetch an object of the corresponding type. Still there is a better way of doing that.
A lookup table can be used to map input strings to the required objects:
action = table.lookup (action_name); // Retrieve an action by its name
if (action == null) ... // No matching action is found
The initialization code would take care of creating the required objects, for example
table ["edit"] = new EditAction ();
table ["view"] = new ViewAction ();
...
This is the basic scheme that can be extended to cover more details, such as additional arguments of the action objects, normalization of the action names before using them for table lookup, replacing a table with a plain array by using integers instead of strings to identify requested actions, etc.
I've been thinking about this problem probably more than the rest developers that I met. Most of them are totally unaware cost of maintaining long nested if-else statement or switch cases. I totally understand your problem in applying solution called "Replace conditional with polymorphism" in your case. You successfully noticed that polymorphism works as long as object is already selected. It has been also said in this tread that this problem can be reduced to association [key] -> [class]. Here is for example AS3 implementation of the solution.
private var _mapping:Dictionary;
private function map():void
{
_mapping["view"] = new ViewAction();
_mapping["edit"] = new EditAction();
_mapping["sort"] = new SortAction();
}
private function getAction(key:String):BaseAction
{
return _mapping[key] as BaseAction;
}
Running that would you like:
public function run(action:String):void
{
var selectedAction:BaseAction = _mapping[action];
selectedAction.apply();
}
In ActionScript3 there is a global function called getDefinitionByName(key:String):Class. The idea is to use your key values to match the names of the classes that represent the solution to your condition. In your case you would need to change "view" to "ViewAction", "edit" to "EditAction" and "sort" to "SortAtion". The is no need to memorize anything using lookup tables. The function run will look like this:
public function run(action:Script):void
{
var class:Class = getDefintionByName(action);
var selectedAction:BaseAction = new class();
selectedAction.apply();
}
Unfortunately you loose compile checking with this solution, but you get flexibility for adding new actions. If you create a new key the only thing you need to do is create an appropriate class that will handle it.
Please leave a comment even if you disagree with me.
public abstract class BaseAction
{
public abstract void doSomething();
}
public class ViewAction : BaseAction
{
public override void doSomething() { // perform a view action here... }
}
public class EditAction : BaseAction
{
public override void doSomething() { // perform an edit action here... }
}
public class SortAction : BaseAction
{
public override void doSomething() { // perform a sort action here... }
}
string action = "view"; // suppose user can pass either
// "view", "edit", or "sort" strings to you.
BaseAction theAction = null;
switch (action)
{
case "view":
theAction = new ViewAction();
break;
case "edit":
theAction = new EditAction();
break;
case "sort":
theAction = new SortAction();
break;
}
theAction.doSomething();
So I don't need conditionals here, but I still need it to decide which BaseAction type to instantiate first. There's no way to completely get rid of the conditionals.
Polymorphism is a method of binding. It is a special case of thing known as "Object Model". Object models are used to manipulate complex systems, like circuit or drawing. Consider something stored/marshalled it text format: item "A", connected to item "B" and "C". Now you need to know what is connected to A. A guy may say that I'm not going to create an Object Model for this because I can count it while parsing, single-pass. In this case, you may be right, you may get away without object model. But what if you need to do a lot of complex manipulations with imported design? Will you manipulate it in text format or sending messages by invoking java methods and referencing java objects is more convenient? That is why it was mentioned that you need to do the translation only once.
You can store string and corresponding action type somewhere in hash map.
public abstract class BaseAction
{
public abstract void doSomething();
}
public class ViewAction : BaseAction
{
public override void doSomething() { // perform a view action here... }
}
public class EditAction : BaseAction
{
public override void doSomething() { // perform an edit action here... }
}
public class SortAction : BaseAction
{
public override void doSomething() { // perform a sort action here... }
}
string action = "view"; // suppose user can pass either
// "view", "edit", or "sort" strings to you.
BaseAction theAction = null;
theAction = actionMap.get(action); // decide at runtime, no conditions
theAction.doSomething();
The switch is simple and looks OK. I don't think it would be that secure if a user could feed in a class name and you could directly use it without a switch conditional.
For obtaining data though, Coders have been known to use a look up table loop to get extra data reducing it to one if in an array look up search. Still thinking the switch looks simple enough to understand but would be cumbersome if you had 100s of choices.

What's the convention for extending Linq datacontext with set based helper operations specific to one collection of entities only

I might be vaguing out here but I'm looking for a nice place to put set based helper operations in linq so I can do things like;
db.Selections.ClearTemporary()
which does something like
db.DeleteAllOnSubmit(db.Selections.Where(s => s.Temporary))
Since I can figure out how to extend Table<Selection> the best I can do is create a static method in partial class of Selection (similar to Ruby) but I have to pass in the datacontext like;
Selection.ClearTemporary(MyDataContext)
This kind of sucks because I have two conventions for doing set based operations and I have to pass the data context to the static class.
I've seen other people recommending piling helper methods into a partial of the datacontext like;
myDataContext.ClearTemporarySelections();
But I feel this makes the dc a dumping ground for in-cohesive operations.
Surely I'm missing something. I hope so. What's the convention?
public static class LinqExtensions
{
public static void Clear<T>(this Table<T> t, Expression<Func<T,bool>> pred)
{
t.DeleteAllOnSubmit(t.Where(pred));
}
}
Usage:
db.Selections.Clear(x => x.Temporary);
If needed, the DataContext can be accessed from a Table<T>.
I'm thinking of creating nested classes as partials of the datacontext plus a getter that initializes and returns the nested class
public SelectionsHelperClass SelectionsHelper {
get {
return new SelectionsHelperClass(Selections)
}
}
This way I can do db.SelectionsHelper.ClearTemporary() without passing in the context while keeping set based operations (collection operations) specific to Selections logically together. I haven't tested this.
Something I forgot to mentioned is that reason I want these helpers is that they are frequently shared by some but not all controllers in an asp mvc app and I'm looking for a place to refactor them too.

Resources