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,582
|
Comments: 51,212
Privacy Policy · Terms
filter by tags archive
time to read 2 min | 288 words

Roy is talking about certain dogmatic approaches in the ALT.Net community with regards to Type Mock. Go and read the comments, the thread is far more interesting than just the post.

Now that you have done so, let me try to explain my own thinking about this.

Type Mock has the reputation of supporting unmaintainable practices. You can argue if this reputation is accurate or not, but it is there. In fact, from Type Mock's own homepage:

Saves time by eliminating code refactoring and rewriting just to make it testable

Here is the deal, I don't think that you should eliminate code refactoring. I think that avoiding dealing with technical debt is a losing proposition in the long term.

Certainly Type Mock enables me to ignore highly coupled design and still be able to create tests for it.

Is this of value? Absolutely!

Is this desirable? I don't believe so.

Can I use Type Mock to create software with decoupled, testable design? Of course I can.

But then there is the question: what do I get from Type Mock?

Quite a lot of other goodies, actually:

  • Integration with the IDE
  • Understanding debugger func-eval (and evil feature which can cause no end of pain when doing mocking)
  • Visual Mock Tracer
  • Other things that I am not aware of because I am not a Type Mock user

The question whatever you should use it or not depends on your situation, as the author of Rhino Mocks, I don't think that I can give an unbiased opinion.

time to read 3 min | 436 words

Frankly, I am quite amazed that I even need to write this post. Source Control is such a basic part of the development process that I didn't want to believe there could be anything to say about it.

In the previous release of Entity Framework, there were deal breaker issues in the source control story. In short, it didn't work. I installed Visual Studio 2008 SP1 Beta to check how the new bits behave.

Let us start from the simplest scenario, defining a model with two classes, and commit to source control:

image

Now, let us say that Jane wants to add a Total property to the Order class:

image


At the same time, Joe is adding a Name property to the Customer class:

image

Jane commits first, and then Joe attempts to commit. Here is the result:

image

This is bad.

In fact, I would say that calling this unacceptable is not going far enough.

I made two unrelated modifications in the model, something that happens... all the time, and it puked on me.

This is not an acceptable Source Control story.

Now, to be fair, I dug a little deeper and tried to find what has cause the conflict. Here is what I find in the Model1.edmx file:

image

The conflict is in the visualization section of the file. This is a huge improvement over the previous version, but is is still broken. Leaving aside the fact that I have no idea why the visualization information is in the same file as the actual model, I shouldn't get merge conflicts on this trivial a change.

I didn't check the generated code, but there were conflicts there as well, which might cause additional issues. They could be regenerated, I assume.

In the end, I was able to get to the model that I wanted, after manually fixing the merge conflicts:

image

In summary, this is a huge improvement from the previous version, but it is still fall far from the minimum expected bar.

Please note that I have tested the most trivial scenario that I could, I have no idea what the behavior would be when dealing with more advance scenarios.

time to read 1 min | 129 words

After the pain of VS 2005 SP1 (which killed my machine, as a matter of fact), I decided to install the SP1 beta for VS2008 on a clean VM. That VM is a simple install of the OS + VS 2008, that is all.

Here is the result of installing VS 2008 SP1 Beta. I have no idea what happened, at one point it was installing, now it is rolling back.

image

I suppose I could try to figure out what is going on, by hunting in the logs and trying the cargo cult approaches.

But I have a simpler solution, just avoid the whole thing. Is it too much to ask that the installer will work?

time to read 1 min | 200 words

You probably heard me talk about zero friction and maintainability often enough in the past. But they were always separate subjects. When I prepared for my Zero Friction talk, I finally figured out what is the relation between the two.

I talk about zero friction as a way to reduce pain points in development. And I talk about maintainability as a way to ensure that we build sustainable solutions.

Let us go back a step and try to realize why we even have the issue of maintainability. Bits do not rot, why am I so worried about proactively ensuring that we will keep the code in a good shape?

As it turn out, while code may not rot, the design of the application does. But why?

If you have an environment that has friction in it, there is an incentive for the developers to subvert the design in order to produce a quick fix or hack a solution to solve a problem. Creating a zero friction environment will produce a system where there is no incentive to corrupt the design, the easiest thing to do is the right thing to do.

By reducing the friction in the environment, you increase the system maintainability

time to read 2 min | 243 words

3 Months ago I released Rhino Mocks 3.4, we have made some great improvement to Rhino Mocks in the meantime, and it is time for a new release. I generally don't believe in beta releases for Rhino Mocks, but this time we are coming up with a new syntax, and I want to get additional external input before we make a final release on that.

The biggest new feature is the new AAA syntax, which you can read about in the relevant post, but we had a few other new things as well.

  • CreateMock() is deprecated and marked with the [Obsolete] attribute. Use StrictMock() instead.
  • Better handling of exception in raising events from mock objects
  • Fixing an issue with mock objects that expose methods with output parameter of type System.IntPtr.
  • Allowing to return to record mode without losing expectations, thanks to Jordan Terrel, for submitting this patch.

I intend to write a lot more documentation about the new AAA syntax, but for now, you can visit the tests for the feature, to see how it works.

As usual, you can find the bits here.

Note that this release if for .Net 3.5 only. Rhino Mocks 3.5 RTM will be for .Net 2.0 and 3.5, but I am focusing on the capabilities that I can get from the 3.5 platform at the moment.

time to read 3 min | 432 words

I intend to release the new version of Rhino Mocks soon, and I wanted to show the new syntax that I have been working on. I still need to write more thorough documentation, but I think that just the syntax should be a pretty good indication of how things are going.

Without further ado, here is the code:

[Test]
public void WhenUserForgetPasswordWillSendNotification_WithConstraints()
{
    var userRepository = MockRepository.GenerateStub<IUserRepository>();
    var notificationSender = MockRepository.GenerateStub<INotificationSender>();

    userRepository.Stub(x => x.GetUserById(5)).Return(new User { Id = 5, Name = "ayende" });

    new LoginController(userRepository, notificationSender).ForgotMyPassword(5);

    notificationSender.AssertWasCalled(x => x.Send(null),
        options => options.Constraints(Text.StartsWith("Changed")));
}

[Test]
public void WhenUserForgetPasswordWillSendNotification_WithArgMatchingInTheLambda()
{
    var userRepository = MockRepository.GenerateStub<IUserRepository>();
    var notificationSender = MockRepository.GenerateStub<INotificationSender>();

    userRepository.Stub(x => x.GetUserById(5)).Return(new User { Id = 5, Name = "ayende" });

    new LoginController(userRepository, notificationSender).ForgotMyPassword(5);

    notificationSender.AssertWasCalled(x => x.Send(Arg<string>.Matches(s => s.StartsWith("Changed"))));
}

[Test]
public void WhenUserForgetPasswordWillSendNotification_WithArgumentMatching()
{
    var userRepository = MockRepository.GenerateStub<IUserRepository>();
    var notificationSender = MockRepository.GenerateStub<INotificationSender>();

    userRepository.Stub(x => x.GetUserById(5)).Return(new User { Id = 5, Name = "ayende" });

    new LoginController(userRepository, notificationSender).ForgotMyPassword(5);

    notificationSender.AssertWasCalled(x => x.Send("Changed password for ayende"));
}


[Test]
public void WhenUserForgetPasswordWillSendNotification_UsingExpect()
{
    var userRepository = MockRepository.GenerateStub<IUserRepository>();
    var notificationSender = MockRepository.GenerateMock<INotificationSender>();

    userRepository.Stub(x => x.GetUserById(5)).Return(new User { Id = 5, Name = "ayende" });
    notificationSender.Expect(x => x.Send(null)).Constraints(Text.StartsWith("Changed"));

    new LoginController(userRepository, notificationSender).ForgotMyPassword(5);

    notificationSender.VerifyAllExpectations();
}

The class under test is:

public class LoginController
{
    private readonly IUserRepository repository;
    private readonly INotificationSender sender;

    public LoginController(IUserRepository repository, INotificationSender sender)
    {
        this.repository = repository;
        this.sender = sender;
    }

    public void ForgotMyPassword(int userId)
    {
        User user = repository.GetUserById(userId);
        sender.Send("Changed password for " + user.Name);
    }
}

DevTeach Summary

time to read 4 min | 642 words

Well, DevTeach Toronto is over, and so it my blogging hiatus. I haven't had time to blog because there was so much to do and take part of.

Now that it is officially over, I can look back and say that DevTeach is still my favorite conference. Leaving aside the great speaker and talk line up (thanks James, and thanks Scott for doing it on the last two DevTeach confs), what I really like about DevTeach is the interaction with the attendees and the amount of face to face time that you get with everyone. I haven't been able to crack what it is that makes DevTeach special in this way, but I have been to other big conferences, and they were good, but they weren't the same.

In short, in you have can make a conference, you really want to make it DevTeach.

I am feeling somewhat wrung out at the moment, the last week was intense. I had five talks and a panel discussion (which will be available on DotNetRocks! ) , and at some point it felt like playing musical chairs. I like presenting, make no mistake, but there is no denying that giving a talk is a high energy expenditure event.

Overall, I am happy with the way the talks went. I talked about:

  • Rapid (maintainable) web development with MonoRail
  • Advance usages of Inversion of Control containers
  • Writing Domain Specific Languages in Boo
  • Object Relational Mapping += 2: More then just data <-> object
  • Building Zero Friction Development Environment

The last talk was a surprise one, I had to fill in for Roy, who was sick (but is getting better). For an off the cuff session, I think it went very well. It was somewhat like posting to my blog, live and in speech, instead of writing. At least, that was how it felt, far more informal and more abstract than most of my talks. It has also given me the chance to clarify some of my thinking in the area of zero friction development and why this should be a goal.

The Advance IoC and Advance OR/M talks were pure fun. Fundamentals are important, but there isn't enough discussion about what happens after you grok the fundamentals as I would like to see.

Of course, I know that the pace of those talks is fairly... daunting. I am trying to cover in one hours concepts that took me months and years to figure out. I am not trying to impart the actual knowledge in those talks, there is just not enough time for it, but I am trying to point the way to interesting approaches, the advantages that using those approaches gives you, and where you should explore further.

The panel discussion, which was recorded as a Dot Net Rocks podcast, talked about The Future of .Net. Me, Ted Neward and Scott Bellware sat and talked about this for a while. I think that it was a good discussion, but I really feel the need to find something else to point as the negative examples. We have been beating the same horse for too long. I accept nominations, by the way.

Too many hallway discussions and side talks to count or articulate, I am afraid.

Greg's talk about DDDD was interesting, we talked about it afterward, and I think that we are much closer in our thinking that it would appear on the outside. A lot of the things that Greg objects to are things that I would hurry to avoid as well. We take different approaches to avoiding them, most probably because we tend to build very different applications.

In summary, DevTeach rocked!

I had a lot of fun, and baring intervention from a higher power, I definitely intend to be in the next one.

time to read 1 min | 165 words

That was an interesting talk, Owen Rogers talked about how to setup an Operation Database in order to get more visibility on your production system. This is the first time that I sat in a talk that is a "Release It!" influenced talk, and it was very interesting.

The type of Operation Database is focused on adding more information for the developers, rather than exposing more information to the operation team. What was especially interesting is that the amount of data being capture is very small. The standard log data (time, message, exception, etc) and a command log, which I think about as a message handling log. This log capture some statistics about messages / commands that the application has handled. Message size (in & out), time, processing time, etc.

From that, you can get pretty interesting data about your application (just showing avg. message processing time over a period of time is extremely valuable).

The nice part about this is that the entry cost is basically zero.

time to read 1 min | 94 words

This is the entire Binsor config file for a real application:

import Castle.MonoRail.Framework
import Castle.MonoRail.WindsorExtension
import Rhino.Commons.Facilities from Rhino.Commons.ActiveRecord

facility MonoRailFacility
facility RhinoTransactionFacility
facility ActiveRecordUnitOfWorkFacility:
	assembly = "HibernatingRhinos"

for type in AllTypesBased of IController("HibernatingRhinos"):
	component type.Name, type
	
for type in AllTypes("HibernatingRhinos").WhereNamespaceEq("HibernatingRhinos.Services"):
	component type.GetServiceInterface(), type

And I am pretty confident that I am not going to have to do much in the future with those.

And yes, you can do it with the fluent registration API as well.

FUTURE POSTS

  1. RavenDB GenAI Deep Dive - 6 hours from now
  2. fsync()-ing a directory on Linux (and not Windows) - 3 days from now

There are posts all the way to Jun 09, 2025

RECENT SERIES

  1. Webinar (7):
    05 Jun 2025 - Think inside the database
  2. Recording (16):
    29 May 2025 - RavenDB's Upcoming Optimizations Deep Dive
  3. RavenDB News (2):
    02 May 2025 - May 2025
  4. Production Postmortem (52):
    07 Apr 2025 - The race condition in the interlock
  5. RavenDB (13):
    02 Apr 2025 - .NET Aspire integration
View all series

Syndication

Main feed Feed Stats
Comments feed   Comments Feed Stats
}