views:

71

answers:

3

I have created a class library (assembly) that provides messaging, email and sms. This class library defines an interface IMessenger which the classes EmailMessage and SmsMessage both implement.

I see this is a general library that would be part of my infrastructure layer and would / can be used across any development.

Now, in my application layer I have a class that requires to use a messaging component, I obviously want to use the messaging library that I have created. Additionally, I will be using an IoC container (Spring.net) to allow me to inject my implementation i.e. either email or sms.

Therefore, I want to program against an interface in my application layer class, do I then need to reference my message class library from my application layer class?

Is this tightly coupling my application layer class to my message class library?

Should I be defining the interface - IMessenger in a seperate library?

Or should I be doing something else?

+1  A: 

It all depends on what your future plans for IMessenger are. Personally I do not find that having the interface as well as a few sample implementations in the same assembly is a bad thing. If someone wants to provide a new implementation of IMessenger they will have to do it in another assembly, and in the course of bringing in your assembly they will get EmailMessage, SmsMessage, etc. For a lightweight assembly I view that as not a big deal, since it saves you the effort of referencing both your "interface" and "implementation" assemblies every time you want to use one.

If your implementation classes reference other code related to your organization or anything that you wouldn't want exposed, then it would make more sense to separate IMessenger into its own assembly and just distribute that as needed.

Brad
@Brad: How would you classify a light weight assembly? By its physical size (Bytes) and if so what would be light weight?
David
Essentially, physical size or number of classes. I just mean that if you are re-using that assembly in a lot of applications, it's nicer if you're not bringing in a lot of unrelated business objects, data access classes, etc. But it sounds like this will be an independent library that you use in a lot of projects. Your question should be, "Do I want everyone that needs an IMessenger to know about EmailMessage and SmsMessage [and thus include them], or should users be able to implement an IMessenger without knowing about the existing implementations? [use two separate assemblies].
Brad
+1  A: 

There is nothing wrong with referencing (and thus coupling) the application layer class to the message library. As long as your message library is independent and unaware of its users it is fine.

Moreover, dont over-architect just for the fact of architecture. It should have a purpose and the benefits should be greater than the costs.

Henri
@Henri: I can't agree with you more on your last point!
David
Im glad you do :) Since at the end of the day, that is what it is all about.
Henri
I don't agree. There's a tight coupling, this is not good. It's also important that your app is not aware to the implementations of its collaborators. And it's not over-architecting, they're just good design principles.
bloparod
A: 

My answers to your questions:

  • "Therefore, I want to program against an interface in my application layer class, do I then need to reference my message class library from my application layer class?" NO

  • "Is this tightly coupling my application layer class to my message class library?" YES

  • "Should I be defining the interface - IMessenger in a seperate library?" YES

If you're using an IoC container, PLEASE inject the dependencies and don't couple your app to infraestructure implementations.

My implementation would be to put the IMessenger interface in the application layer, in order to allow my app objects to talk to an interface, no matter its implementations. I would have the general email and SMS sending in a separate assembly, and they implement IMessenger. The injection, obviously, is performed by an IoC container.

The application layer shouldn't know the infraestructure layer.

This is a good page to see this kind of designs: Hexagonal Architecture.

bloparod
@bloparod thanks for your answer. If IMessenger is defined in the application layer doesn't this then mean that the assembly that provides the implementations would then have to reference the assembly in the application layer that defines the IMessenger interface?
David
@David: Yes, the assembly with the implementations has to reference the assembly that exposes IMessenger. The dependency is inverted (application layer doesn't know about infraestructure stuff), and the implementations should be resolved by Spring.net.
bloparod