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;
[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)
{
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.