Oren Eini

CEO of RavenDB

a NoSQL Open Source Document Database

Get in touch with me:

oren@ravendb.net +972 52-548-6969

Posts: 7,567
|
Comments: 51,184
Privacy Policy · Terms
filter by tags archive
time to read 4 min | 682 words

Assume that I have this piece of code: 
public interface InterfaceWithExplicitImpl<T>
{
   IEnumerator<T> GetEnum1();
}
Now, check the picture. This is 100% repreducable, but only under very specific set of scenarios (basically, running System.Reflection.Emit stuff). I am not sure how exactly I am supposed to handle this sort of an issue.
 
WTF
 
Here is the code to repreduce the issue:
You need to reference Dynamic Proxy 2, but this code produce stuff that I would bet is flat out impossible.
 
   1:   class Program
   2:   {
   3:       static void Main(string[] args)
   4:       {
   5:           Console.WriteLine("Before it has {0} methods", typeof(MyInterfaceWithExplicitImpl<int>).GetMethods().Length);
   6:           
   7:           ProxyGenerator generator = new ProxyGenerator(new PersistentProxyBuilder());
   8:           generator.CreateInterfaceProxyWithoutTarget(typeof(MyInterfaceWithExplicitImpl<int>), new StandardInterceptor());
   9:           generator = new ProxyGenerator(new PersistentProxyBuilder());
  10:           generator.CreateInterfaceProxyWithoutTarget(typeof(MyGenericInterface<object>),
  11:                                                           new Type[] { typeof(MyInterfaceWithExplicitImpl<int>) },
  12:                                                           new StandardInterceptor());
  13:   
  14:   
  15:           Console.WriteLine("After it has {0} methods", typeof(MyInterfaceWithExplicitImpl<int>).GetMethods().Length);
  16:       }
  17:   }
  18:   
  19:   public interface MyInterfaceWithExplicitImpl<T>
  20:   {
  21:       IEnumerator<T> GetEnum1();
  22:   }
  23:   
  24:   public interface MyGenericInterface<T> where T : new()
  25:   {
  26:       T DoSomething(T t);
  27:   }
time to read 2 min | 291 words

At one point in class, I talk about maintainability, and I happened to mention renaming a column in the database.

One of the students got up and started what I can only call a rant on how people that renames columns in the database should be shot in the head and then thrown into the garbage heap. Appernatly proper burial was too good for those monsters that renames columns in the database. I am sure that the story behind this reaction was interesting, and probably funny if you aren't in it.

What interested me that this was such a powerful reaction to a problem that I don't even have. I have run into several of those recently, and I must say that some people has fairly creative solutions to problems that I don't even have.

One company has decide to forbid the use of identity columns all together, and forces all PK generation to be done through counters tables. Again, I don't have the story, but I have a strong feeling that @@IDENTITY is behind it.

At DevTeach I was shown a clever way to work around dependency management on the naked CLR, I was impressed by the inventiveness, but it was an approach that could only be taken so far.

The point of this post is to urge you to take several steps back when you run into something that doesn't makes sense, and try to find a way that does make sense, if you have to do something that you feel the underlying framework/services should do, you are either doing something wrong, or the platform is wrong. In general, it is safer to assume that you are doing something wrong and that there is a better way. Find out!

time to read 2 min | 325 words

So, applying the separation of concerns principal to blog posts again, I wanted to talk about another aspect that had me thinking as a result of teaching .Net. I literally had no idea how complex development was until I had to stand in class and explain the tradeoffs for the various approaches for implementing things. Several things that kept popping up are:

  • Concurrency
  • Multi thread safety (in the abstract, at least) - That one is easy, don't do multi threading. Failing that, don't do multi threading on shared state. Failing that, welcome to the fun world of multi threaded debugging :-)
  • Normalization
  • Ease of use (API wise)
  • Information hiding
  • Exception non-handling *(not a typo)

Those are cross cutting concerns that affect a lot of the actions in the application. When I develop, I don't think that I am really aware for this, I just write code according to the best practices that I pub-sub to, and it usually end up being correct.

Having to implement a solution in front of a class, it is much more difficult, because now I have to articulate these best practices, why they are important and their reasoning. This made me realize how often I do the same without really bothering to go through the entire check list.  Did you know that Rhino Mocks has a mode that is actually safe for multi threading, for instance?

Now I need to re-learn how to forget about all those messy concerns and just build the application the way it is supposed to be, without starting to worry about all of those concerns until I really need to.

Nevertheless, it is pretty amazing that I can spend 30 minutes talking about 15 lines of code, pointing out all the various concerns that it needs to handle, and how it does them. It is amzing and depressing in the same time, we need to handle so much stuff that this is getting ridiculous.

time to read 3 min | 440 words

I am currently teaching an MCPD course for about 20 people, with various programming backgrounds but little to no .Net experience. It is an interesting experience, and I realy like teaching (I get to speak for several hours and they have to listen to me :-) ). Plus, it is a good way to get a close up visual of how the new developers think.

I firmly believe that the only way you can really understand a topic is by having to teach it to someone. You can know something by reading about it, and you may even be able to recall it when you need, and you learn by doing something, but you are only assimilate this stuff when you teach it to someone, because then you have some sort of a coherent mental model in place.

Case in point, transaction isolation levels, I know this stuff, I have certainly used it in many places, I just don't think that I was ever able to really grok that before I had explained it to a class of people. This required not just explaining how it works, but the why, when and where. At the end, I came up much smarter, and I was the teacher :-)

The guys (and gals, but Hebrew is a sexist language, so I am just going to use guys from now on) in the class has various experiences, from assembly programming (and what fun it is to explain OOP to an assembly programmer), through C++ guys, to classic ASP programmers, to .Net programmers that want to know it better. That is an interesting (and challanging) mix.

There is the official curriculum for this course, and I am sort of horrifyingly following that. (At one point, I had to stop the class and do a code review of the example solution, it was very... instructive as a worst practice example.) I have a problem in teaching people stuff that I am not actually using, I feel like I am speaking in two voices here.

Nevertheless, I literally can't teach them the stuff that I use. Not because of the limitations of the course, but simply because to do that would be actively harmful to them. You can't (and shouldn't) try to grasp OR/M before you have a good understanding of SQL and how ADO.NET works. I can figure out how trying to teach IoC would go: "Oren said that we shouldn't use new Xyz()"

It would be harmful because they first need a good foundation, and only then we can build on top of that. I do insist on Single Responsability from the get go, though :-)

time to read 1 min | 149 words

Aaron has a post about some wild ideas about OR/M fetching, specifically, auto-learning fetching strategies. The idea has merit, and the required technicalities are already inside NHibernate, I can imagine a proxy that talks to to fetching strategy to inform it about accessed properties, which would give it the information needed for the next time the same query is made.

But, how do you correlate queries?

I have "Repository<Salary>.FindAll(Where.Salary.Employee == CurrentEmployee);" in several places, in the "list employee salaries page" and in the "calculate tax" service. Each requires a different fetching strategy. Worse, I have this hiding in a method call GetEmployeeSalaries(Employee), so now we can't even use the callsite information to do our smarts.

We can try to do something with stack traces, but I am not sure that this is something that you would really want to do, as this has performance implications of its own.

time to read 2 min | 385 words

Jay Kimble posted in response to Sam Gentile post about Microsoft's future direction. The part that I didn't like was:

Honestly while I understand the whole MVC pattern and why everyone is all gaga... it's not always necessary to go to that extreme.  My understanding has been that MVC is great for web sites that have high traffic...

And short afterward, we have this gem:

I could probably give a number of the DailyWTF entries based on examples from this site

I had the chance of working in systems of exploding complexity, what I have found is that shortchanging the best practices even in the small has a high cost on many levels, testability, maintainability, complexity, etc. The problem is that you start small, thinking you can just hack it done, but when change is required, which is inevitable, you are in for a world of hurt. This kind of thing leads to awkward technical solutions that doesn't solve the root issue, are much more complex than they should, and obfuscate the solution entirely.

Here is the secret about these kind of best practices, done right, they are less costly than the just throwing code at the problem. If you are building non-throwaway code, then I would always suggest to use the best practices, even if you start small.

Jay's point about MVC being applicable only to web sites with high traffic is not correct, MVC is about splitting responsabilities in the application in a consistent manner. It is as application in a toy applications as in a highly scalable ones.

There are a set of patterns that you want to use if you are building truly highly scalable applications, but they really make your life harder for smaller scale applications (the vast majority). But, and this is important, in a properly designed application, it is usually not hard to make significant changes to the application as a whole, and add the best practices that fit your specific scenario.

time to read 1 min | 49 words

Yesterday: 182 emails (disregarding junk) to my personal mailbox.

A lot of those are from mailing lists that I subscribed to, a lot of those are automatic notifications of all sorts (commits, comments, JIRA, etc). But a significant part of it is communicating directly with a lot of people.

time to read 6 min | 1015 words

Let me start out by saying that I know of a lot of people that are doing MVC with WebForms, I am doing it myself right now, which put me in the position to talk about the pain that it brings.  Let us consider the traditional MVC pattern:

Now, in such a pattern, who is supposed to be in control? To drive the application? If you have guessed that the "Controller" is the one that is supposed to be in control, you got the jackpot, but missed the boat (am I mixing methapors here?) as far as WebForms-based MVC platforms are concerned.

The WebForm model, a PageController with complex life cycle, has a direct affect on the structure of the rest of the application. After trying to get true MVC working on WebForms, I now believe it to be impossible to get it to work in a way that would satisfy me. My view on views is that they are:

  • Stupid
  • Presentation logic only
  • Do not affect the rest of the application

For the purpose of this dicussion, I am going to ignore the differences between MVC, MVP, Passive View, etc. I don't have an issue with the view doing data binding, UI logic, etc. The problem is that there are only three models that can be used with WebForms & MVC:

  • Front Controller that later invokes the Page - Basically, the way that MonoRail integrates the WebForm view engine. The problem with that is that ASPX isn't really that smart about stuff, so you end up having to do a lot of stuff in the code behind, which means that you usually need to call the controller for stuff.
    This gives you wierd state issues, where the controller method has run, but then it is called again to get more information that the view is needed.
    The main issue is with this are stuff like pressing a button, which is very hard to do in a web-nice way with WebForms, neccesiating to catch the event in the view and then call to the controller again. Ugly.
    This is probably the best approach, but unless you are doing it with MonoRail, it is also the most expensive one in terms of time and investment. JB has some thoughts about this subject, from using MonoRail & WebForms.
    Even when you are using MonoRail, this is awkward.
  • The Page is calling the Controller's methods. This is what I am using currently, but I find that this introduce the same state based issues that I am trying to avoid (orderring of method calls, etc) and it still gives too much responsability to the view.
    It basically make the view a semi controller, because it is what drives the controller. The most painful parts are stuf like GetPolicies(), GetUsers(), etc, which are called directly on the controller by the view to get the data it needs.
    I could do it the other way around, FillData(IView), I suppose, but that gives me awkward model for the state changes that is required in most complex screens. Basically, the FillData() would need to get the purpose for this, so I would have FillDataForDefaultCustomer, FillDataForChangedCustomer, etc.
    Another issue is that my controllers are inherintly multi-views capable. That is mostly because of the architecture of WebForms & Atlas, this requires me to put some of the stuff that should respond to an Ajax call in a web service or HttpHandler. Those are all going to the same controller (same use case), but there have very different needs.
  • Registering to the view events in the controller. This seems to be a fairly favoraite pattern for MVP in ASP.Net. I have issues with that because we now has strong ties from the view's behavior to the controller behavior. I think that methods like: "void OnLoad(object sender, EventArgs e)" are code smell, and they don't give me much separation from the view. In fact, they are Code Behind done right, without dealing with the UI at all.

To be clear, all three methods give me a few things very important that it is very hard to get from naked WebForms, namely: Separation of Concerns & Testability.

The most problamatic part in this is that it is very hard to get view-ignorance capabilities using the WebForm approach, it is much harder than it should, and the page lifecycle issue is paramount in both view and controller.

My current approach in WebForms MVC is the second approach, but it is very easy to add additonal concerns to the view without noticing, and my controllers looks more like a service class than a true controller.

As you can guess from the title, I don't think that this is somethig that can be solved when using the WebForms framework. The view is so centric to the very idea of WebForms that it is impossible to work without its influence.

I am probably going to do another screen cast on this, but at this point I am giving up. I am fed up with approximations. If you want to do MVC in ASP.Net, you wouldn't be able to get the real thing with WebForms.

FUTURE POSTS

  1. The null check that didn't check for nulls - 9 hours from now

There are posts all the way to Apr 28, 2025

RECENT SERIES

  1. Production Postmortem (52):
    07 Apr 2025 - The race condition in the interlock
  2. RavenDB (13):
    02 Apr 2025 - .NET Aspire integration
  3. RavenDB 7.1 (6):
    18 Mar 2025 - One IO Ring to rule them all
  4. RavenDB 7.0 Released (4):
    07 Mar 2025 - Moving to NLog
  5. Challenge (77):
    03 Feb 2025 - Giving file system developer ulcer
View all series

RECENT COMMENTS

Syndication

Main feed Feed Stats
Comments feed   Comments Feed Stats
}