Tutorial :Organizing assemblies (assembly structure) in C#



Question:

Say you are writing an app like Photoshop where you have effects (filters), etc, should one make each of these filters a separate assembly using a separate project?

The main idea is to have each of these filters as nodes, so think of it like:

sourceImage -> Sharpen -> Darken -> Contrast -> Blur ...  

It seems to me that it would make sense to have dll files like:

[Filters folder]     Sharpen.dll    Darken.dll  Contrast.dll  Blur.dll  

But it would be hard to manage them like that, and that would prevent me to use the internal keyword for class members, right?

So right now I only have 1 dll for all filters.

What's the best practices for organizing assemblies?


Solution:1

I wouldn't restrict yourself to one filter per assembly. You may well want to group assemblies which implement similar functionality - e.g. colour/contrast together, while keeping them separate from very different kinds of filters (e.g. edge enhancing).

Just one bit of anecdotal evidence: I've often seen applications be difficult to manage due to having too many assemblies. I can't remember ever seeing one which had problems because it hadn't split the assemblies up enough. I'm not saying it can't happen - just that I haven't seen it.


Solution:2

Patrick Smacchia author of NDepend tool suggest that the number of assemblies is kept low. Look here. This also implies to a certain level that you use NDepend to manage dependencies between namespaces. Also, compilation is faster if you have less assemblies and deployment is easier.

I would second Reed Copsey that DI (like StructureMap) solution could provide you with extensibility and testability if that's what you are after.


Solution:3

Reasons to have separate assemblies:

  • You can deploy them individually and load them at runtime using reflection (i.e., plugins). But make sure this level of added complexity is worth it.
  • You can separate your business logic from your UI and theoretically (occasionally in practice) have a separate UI.
  • You have an library of utility classes that you might want to use in both a Windows Forms and a ASP.NET application.
  • You can put your business logic in a DLL and then have a DLL of unit tests to exercise that code.
  • Along with the last point, you can configure some assemblies to only build in Debug or Release mode. So you might build your unit test assembly only in Debug mode and not ship it in Release mode. Or you might have an additional helper program (maybe for installation) that only builds for Release.

Reasons to avoid separate assemblies:

  • It adds complexity. Don't organize your code into multiple assemblies just based on a theoretical "modeling" of your program. Make sure the additional complexity actually buys you some greater value.
  • It slows down compiles/builds.
  • You can't have circular references between assemblies, so you have to jump through a lot of hoops and "plumbing abstractions" if you discover that your assembly needs to access classes and methods from a higher-level assembly. For instance, if your Windows Forms UI (.exe) assembly calls into a business logic DLL, the DLL can't reference the UI classes without a lot of messing around with interfaces and passing references across the layers.

I think this is something that comes with experience. My own experience has been that as I've matured as a .NET developer, I've become less inclined to create more assemblies unless there's a very compelling reason.


Solution:4

I think a better way may be to have a Filters assembly with Sharpen, Darken, Contrast, and Blur namespaces for the types in that assembly. It really all depends on how modular you need each bit of functionality to be.


Solution:5

Having separate assemblies makes it much easier to add more without recompilation. In particular, if you use some type of DI solution (like MEF), you can load these assemblies at runtime and inject them into your program.

However, this will require that your main program exposes an appropriate, public interface, so the other assemblies can work with your types. Internal modifiers become trickier, since you'd have to set the internals visible attribute for each assembly you want to have access to your internals.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »