Click here to Skip to main content
Click here to Skip to main content

Allowing (Virtual) Circular References Between Assemblies

, 29 Dec 2011
Rate this:
Please Sign up or sign in to vote.
Circular references aren't allowed between assemblies, but there is a way to do something just as good, or even better.

Imagine you have a business logic assembly, and an entities assembly, with the business assembly referencing the entities assembly.

Now imagine you want to have an entity use an object from the business logic assembly directly, such as a validator component.

At first glance, it seems impossible because the entities assembly can't reference the business logic assembly as that creates a circular reference.

The way to get around this is to introduce a third assembly, let's call it "contracts", because it's going to contain interfaces that both the business and entity assemblies must agree to use.

Both the entities and business logic assemblies reference the contracts assembly, and the business logic references the entities assembly, but the entities assembly needs to only reference the contracts assembly.

Example: In the business logic tier, there is a component called ValidateStrategy:

public class ValidateStrategy : BaseStrategy, IValidateStrategy
{

http://code.google.com/p/sitestarter/source/browse/trunk/Src/App/SoftwareMonkeys.SiteStarter.Business/ValidateStrategy.cs[^]

ValidateStrategy implements the interface IValidateStrategy, which is located in the contracts assembly.

public interface IValidateStrategy : IStrategy
{

http://code.google.com/p/sitestarter/source/browse/trunk/Src/App/SoftwareMonkeys.SiteStarter.Contracts/Business/IValidateStrategy.cs[^]

Now an entity in the entities assembly can contain a property of the type IValidateStrategy:

private IValidateStrategy validator;
/// <summary>
/// Gets/sets the validation strategy used to validate this entity.
/// </summary>
[XmlIgnore]
public IValidateStrategy Validator
{
    get { return validator; }
    set { validator = value; }
}

http://code.google.com/p/sitestarter/source/browse/trunk/Src/App/SoftwareMonkeys.SiteStarter.Entities/BaseEntity.cs#169[^]

Any time the entity is created, loaded, etc., via the business tier, the BaseEntity.Validator property is set to an instance of the ValidateStrategy. Now the entity can use that ValidateStrategy via the IValidateStrategy interface, even without having a direct reference to the concrete class.

public virtual IEntity Create()
{
    Type type = EntityState.GetType(TypeName);
    IEntity entity = (IEntity)Activator.CreateInstance(type);
    
    //...

    AssignValidator(entity);
    
    //...
    
    return entity;
}
 
public virtual void AssignValidator(IEntity entity)
{
    // Assign a validation strategy
    entity.Validator = ValidateStrategy.New(entity);
}

http://code.google.com/p/sitestarter/source/browse/trunk/Src/App/SoftwareMonkeys.SiteStarter.Business/CreateStrategy.cs#27[^]

The entities assembly doesn't reference the business assembly yet it can still use the ValidateStrategy.Validate function via the IValidateStrategy interface.

This approach allows for a lot more flexibility in how assemblies are organised.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

SoftwareMonkeys
SoftwareMonkeys
Australia Australia
Founder of www.softwaremonkeys.net

Comments and Discussions

 
GeneralWhat will be the execution order of these three projects Pinmembererwrwrwr3-Jan-12 2:28 
GeneralRe: Do you mean the build order? I build contracts first, then e... PinmemberSoftwareMonkeys3-Jan-12 20:45 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140709.1 | Last Updated 29 Dec 2011
Article Copyright 2011 by SoftwareMonkeys
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid