Click here to Skip to main content
15,881,803 members
Articles / Programming Languages / C#
Tip/Trick

Allowing (Virtual) Circular References Between Assemblies

Rate me:
Please Sign up or sign in to vote.
5.00/5 (1 vote)
29 Dec 2011CPOL1 min read 22.1K   2
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:


C#
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.


C#
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:


C#
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.


C#
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)


Written By
SoftwareMonkeys
Australia Australia
Founder of www.softwaremonkeys.net

Comments and Discussions

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

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

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