c# - Register Generic Type in Unity Based On Concrete Type -
i'm trying emulate behavior can configure in ninject, using unity instead.
i attempting utilize cached repository pattern, given next classes , interface:
public interface irepository<t> { t get(); } public class sqlrepository<t> : irepository<t> t : new() { public t get() { console.writeline("getting object of type '{0}'!", typeof(t).name); homecoming new t(); } } public class cachedrepository<t> : irepository<t> t : class { private readonly irepository<t> repository; public cachedrepository(irepository<t> repository) { this.repository = repository; } private t cachedobject; public t get() { if (cachedobject == null) { cachedobject = repository.get(); } else { console.writeline("using cached repository fetch '{0}'!", typeof(t).name); } homecoming cachedobject; } } basically, time application uses irepository<t>, should instance of cachedrepository<t>. within of cachedrepository<t> should fetch actual sql repository of sqlrepository<t>. in ninject, have accomplished using following:
ninjectmodule.bind(typeof(irepository<>)).to(tyepof(sqlrepository<>)).wheninjectedexactlyinto(tyepof(cachedrepository<>)); ninjectmodule.bind(typeof(irepository<>)).to(tyepof(cachedrepository<>)); in unity, how accomplish same thing? have version non-generic repositories works:
unitycontainer container = new unitycontainer(); container.registertype<iwidgetrepository, cachedwidgetrepository>(new injectionmember[] { new injectionconstructor(new sqlwidgetrepository()) }); but syntax won't work @ generic repository, since can't new sqlrepository<> without having syntax error. ideas?
assuming don't want register every individual possible generic, this:
container.registertype<irepository<things>, cachedrepository<things>>(new injectionmember[] {new injectionconstructor(new sqlrepository<things>())}); container.registertype<irepository<otherthings>, cachedrepository<otherthings>>(new injectionmember[] {new injectionconstructor(new sqlrepository<otherthings>())}); you instead utilize custom injection factory, fancy way of saying "write own mill function."
// inquire unity create 1 of these, has resolve irepository<things> public class usesthings { public readonly irepository<things> thingsrepo; public usesthings(irepository<things> thingsrepo) { this.thingsrepo = thingsrepo; } } class programme { static void main(string[] args) { var container = new unitycontainer(); // define custom injection factory. // uses reflection create object based on requested generic type. var cachedrepositoryfactory = new injectionfactory((ctr, type, str) => { var generictype = type.generictypearguments[0]; var sqlrepotype = typeof (sqlrepository<>).makegenerictype(generictype); var sqlrepoinstance = activator.createinstance(sqlrepotype); var cachedrepotype = activator.createinstance(type, sqlrepoinstance); homecoming cachedrepotype; }); // register our fancy reflection-loving function irepository<> container.registertype(typeof(irepository<>), typeof(cachedrepository<>), new injectionmember[] { cachedrepositoryfactory }); // utilize unity resolve var usesthings = container.resolve<usesthings>(); usesthings.thingsrepo.get(); // "getting object of type 'things'!" usesthings.thingsrepo.get(); // "using cached repository fetch 'things'!" } } c# generics inversion-of-control ninject unity-container
No comments:
Post a Comment