Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Allowing (Virtual) Circular References Between Assemblies

0.00/5 (No votes)
29 Dec 2011 1  
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 has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here