views:

772

answers:

4

I have the following situation:

1) A project MyCompany.MyProject.Domain which contains my domain model, and partial classes (such as Contact).

2) I want to 'extend' (by partial class, not extension method) my Contact class with a property "Slug" which will give me a simple URL friendly text representation of first and last name.

3) I have a string extension method ToSlug() in my 'Utility' project MyCompany.MyProject.Utilities which does exactly what I want in 2).

4) The problem: My Utility project is already referencing my domain project which means that I can't get the domain project to see the utility project's ToSlug() method without causing circular reference.

I'm not keen on creating another project to solve this, and I really want to keep the Slug logic shared.

How can I solve this?

+1  A: 

copy ToSlug method to Domain project and Delegate Utility's ToSlug call to this new method

zoli
'Delegate Utility's ToSlug call to this new method' - please clarify? How?
Alex
this was my initial thought also - but I assumed that the domain wasn't shared thus not allowing the library of extension to load. I could have been wrong.
Preet Sangha
+3  A: 

Your Utility project referencing your MyCompany.MyProject.Domain seems like a bit of a code smell. I'm assuming here that these are utilities that specifically work on domain objects--if that's the case, then why don't you include MyCompany.MyProject.Utilities within your Domain project (naturally, modifying the namespace accordingly)?

In any case, the normal way to break these kinds of dependencies is to abstract what is required by one project into a set of interfaces, and encapsulate those in a separate assembly. Before doing that though, make sure that what you're doing conceptually is the right thing.

In your particular situation though, consider introducing an interface, viz., INameHolder:

public interface INameHolder
{
    string FirstName { get; set; }
    string LastName { get; set; }
}

Then Contact implements INameHolder. INameHolder exists in another assembly, let's call it MyCompany.MyProject.Domain.Interfaces.

Then your Utilities project references Interfaces (not Domain) and so does Domain, but Interfaces doesn't reference anything--the circular reference is broken.

Eric Smith
I'll probably go with this.... experimenting right now.
Alex
+2  A: 

If you cannot share the domain (probably right) and it must consume the logic from a shared library then then you really have to introduce a another assembly.

Or you could load the logic at runtime in the domain by reflection in the domain to access the dependent library. Its not hard just breaks compile time checking.

Preet Sangha
+2  A: 

If you're sure about keeping the code in the utility DLL (Eric's answer seems smart to me), then you could create an interface in your utility project, pass that interface as a parameter to your ToSlug method and then have your domain object implement the interface.

Paddy