How to handle multiple instances of the same type (repositories)

75 views
Skip to first unread message

kuss...@googlemail.com

unread,
Dec 10, 2009, 2:20:59 AM12/10/09
to structuremap-users
Hi,

i've got an application where are multiple implementations of
repository interfaces like this:

IMemberRepository => SqlMemberRepository, OracleMemberRepository, ....

I handled the configuration of sm with a RepositoryRegistry and a
custom type scanner that add each implementation of a repository
interface to the configuration by its type name like shown below:

registry:
...
Scan(x =>
{
x.AssembliesFromPath
(Environment.ApplicationBinPath);
x.With<RepositoryScanner>();
});

scanner:
...
public void Process(Type type, PluginGraph graph)
{
try
{
if (type.IsImplementationOf<IRepository>() &&
type.IsClass && !type.IsAbstract)
{
//get the repository interfaces that this class
implements
var implementations = type.GetInterfaces().Where(
t => t.Name.EndsWith("Repository") && t.Name !
= "IRepository");

//add all implementations to the configuration
if (implementations != null)
{
foreach (var implementation in
implementations)
graph.AddType(implementation, type,
type.Name);
}
}
}
catch (Exception e)
{
LOGGER.FatalException("Failed to process repository.",
e);
throw;
}
}

My Problem is how to handle retrieving of types. The application has
configuration settings that describes which implementation should be
used (all Sql implementations or all Oracle implementations). I know
if for example Oracle is configured as the default provider the
Requested type for IMemberRepository must be the one with name
OracleMemberRepository. But how do i configure sm to use this rule. My
first approach was to wrap ObjectFactory.GetInstance to determine the
desired instance name and then call GetInstance on sm to retrieve it.
But this is a mess with the BuildUp method.

Can anybody give me a hint to solve this problem or do you know o
complete better approach to handle the situation where i have multiple
implementations that are only know at runtime.

Thanks in advance

Rene

Jeremy Miller

unread,
Dec 18, 2009, 9:45:32 PM12/18/09
to structuremap-users
The easiest thing I think would be to use Profiles. When you do the
type scanning and create the Oracle & Sql Server objects, register
each with the PluginGraph as the "Oracle" or "Sql Server" profile. At
app startup time, read the "Database" from your config, then go:

ObjectFactory.Profile = "Oracle" or "Sql Server"

To set it up in the PluginGraph,

go -->

graph.ProfileManager.SetDefault("Oracle", pluginType, new
ConfiguredInstance(type))

where "pluginType" = IMemberRepository
and "type" = OracleMemberRepository


A better way might be to create a more generic IRepository that has
generic Find<T>() or Query<T>() methods that is consumed by the
tighter "MemberRepository" like this:

public class MemberRepository
{
public MemberRepository(IRepository rep)
{

}

}

Then you only need to switch the one object between OracleRepository,
SqlServerRepository, and InMemoryRepository in one go.


Good luck, and I'll answer the next question faster,

Jeremy

On Dec 10, 1:20 am, "kuss.r...@googlemail.com"

kuss...@googlemail.com

unread,
Dec 20, 2009, 3:06:40 PM12/20/09
to structuremap-users
Thanks for your help Jeremy. I think i'll use the profile solution.
Reply all
Reply to author
Forward
0 new messages