Ricardo Cavalcanti has raised question on fluent passing of parameters into the queries encapsulated by the QueryFor (specification) pattern.
Let’s talk about the easiest option of passing parameters, first. It requires no new code at all and is just about chaining queries:
var list = customers
.Find<ImportantCustomers>()
.Where(c => c.City == "Ufa");
Where comes from the in line extension method provided by Linq.
However, in certain situations Linq might be not enough. This involves queries that encapsulate come complex business logic or require parameter pre-processing, that you want to hide away.
Continue reading ‘Linq queries with parameters for your ORM IRepository’
Let’s get back to the discussion from XPO+ORM+IOC series on Implementing ORM-independent Linq queries.
As you can see from the previous post, there are 3 options to abstract away queries in a testable manner (and we will add one theoretical one for the Boo):
1. Put queries right into some domain-specific repository implementation (i.e.: CustomerRepository.FindImportantCustomers) and ask the container about it.
- Pro: Simple and looks as if there is no logical separation between the repository and queries
- Con: Low scalability
- Con: Coupled code that would take some effort to test
2. Put queries into the extensions that use Repository[T].Find method.
- Pro: A bit more abstraction and testability, than in the previous option
- Con: Does not make a lot of sense
Continue reading ‘Options of separating queries from the ORM Repository’
In the previous post in ORM+IoC series we’ve managed to decouple away from the ORM-based collection and the literal-based syntax (which was bound to the logics of eXpress Persistent Objects ORM).
In this post we’ll try to get rid of all the remaining coupling (while making it unit-testable) and even add domain-based extensibility that is easy to implement.
Let’s modify the code:
public sealed class DisableAllAccounts : ICommand
{
private readonly IOrderedQueryable<IAccount> _accounts;
private readonly ILog _log;
public DisableAllAccounts(IOrderedQueryable<IAccount> accounts, ILog log)
{
_accounts = accounts;
_log = log;
}
public void Execute()
{
_log.Write("Disabling accounts:");
var accounts = from c in _accounts
where (c.Disabled == false)
select c;
foreach (var account in accounts)
{
IComment comment = account.CreateComment();
comment.Text = string.Format("Account {0} was disabled on {1}",
account.FirstName, DateTime.Now);
comment.Save();
account.Disabled = true;
account.Save();
}
}
}
Continue reading ‘How to implement unit-testable abstraction and reusable domain models with IoC + ORM?’
One of the most important features of any proper development architecture, environment or process, is that the synergy (network) effects accumulate, if you keep doing the right things. IoC/DI, unit testing and TDD, continuous integration - all these just form up the external side of how everything works. They simply help (or force) to shape the logics of the development to make everything fold smoothly and let your solutions accumulate the benefits.
Now, let us get back to the IoC+ORM series and take one more look at the ICommand implementation from the last post. It could be improved quite a bit:
public sealed class DisableAllAccounts : ICommand
{
private readonly IRepository<Account> _accounts;
private readonly ILog _log;
public DisableAllAccounts(IRepository<Account> accounts, ILog log)
{
_accounts = accounts;
_log = log;
}
public void Execute()
{
_log.Write("Disabling accounts:");
_accounts.CriteriaString = "Disabled=0";
foreach (var account in _accounts)
{
_log.Write(account.Name);
account.Disabled = true;
account.Save();
}
}
}
Things become better as we throw out things that do not fit well. So let us remove our custom IRepository<> from this picture (along with the FireCollection behind it) and get rid of the string literal in favor of something that is compiler-checked
Continue reading ‘How to use ORM (XPO), IoC, C# 3.5 syntax, Linq and .NET 2.0 together?’
Latest Comments