Determine if a Type/Name has been Registered

May 7, 2009 at 4:03 AM
Just tried introducing Funq into an existing code-base, and I struck a hurdle.

In this code, I'm using a Dictionary<Foo, Func<Page>> so I can resolve an instance of a Page by name. I have ripped that out and replaced it with a Container and calls to ResolveNamed(Foo.Code). That part has worked well.

However, in one part of my code I want to get a list of "Foo" instances that are in the dictionary. The equivalent code for Funq would be something like:

    fullListOfFoos.Where(f => container.CanResolve<Foo>(f.Code));

... or possibly:

    fullListOfFoos.Where(f => container.IsRegistered<Foo>(f.Code));

... except obviously there's no methods like those on Container.

I don't actually need to resolve the instance mapped to the Foo.Code in question - I just need to know if it's there. I think this should be a pretty fast lookup into the internal dictionary in the container. Does that sound like something you could add to Funq?

Cheers,
Matt
Coordinator
May 7, 2009 at 11:57 AM
Sounds useful.
How would that work in the presence of potential constructor arguments?
May 7, 2009 at 12:02 PM
I guess "CanResolve" might need overloads to take arguments into account.
It would certainly help my code - I'm using it to filter a menu (only show menu items that can resolve to a page) which means I'm instantiating everything just to populate a menu.

From: [email removed]
Sent: Thursday, May 07, 2009 9:57 PM
To: [email removed]
Subject: Re: Determine if a Type/Name has been Registered [funq:55546]

From: dcazzulino

Sounds useful.
How would that work in the presence of potential constructor arguments?
Coordinator
May 9, 2009 at 2:32 AM

Would you like to work on a patch for this?

Thanks in advance!

May 9, 2009 at 7:07 AM
I really should, because I'd like to get to know the code a bit more intimately than what I've learned from your screencasts. If I get a chance I will take a look this week.

From: [email removed]
Sent: Saturday, May 09, 2009 12:32 PM
To: [email removed]
Subject: Re: Determine if a Type/Name has been Registered [funq:55546]

From: dcazzulino

Would you like to work on a patch for this?

Thanks in advance!

May 10, 2009 at 11:40 PM
Edited May 10, 2009 at 11:58 PM

Unless I've missed something, this turned out to be remarkably easy (a testament to how elegant the code is, I guess)!

I've just added the following to the Container class:

        /// <include file='Container.xdoc' path='docs/doc[@for="Container.CanResolve{TService, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6}"]/*'/>
        public bool CanResolve<TService, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6>(string name, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6)
        {
            return GetEntry<TService, Func<Container, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TService>>(name, false) != null;
        }

        /// <include file='Container.xdoc' path='docs/doc[@for="Container.CanResolve{TService, TArg1, TArg2, TArg3, TArg4, TArg5}"]/*'/>
        public bool CanResolve<TService, TArg1, TArg2, TArg3, TArg4, TArg5>(string name, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5)
        {
            return GetEntry<TService, Func<Container, TArg1, TArg2, TArg3, TArg4, TArg5, TService>>(name, false) != null;
        }

        /// <include file='Container.xdoc' path='docs/doc[@for="Container.CanResolve{TService, TArg1, TArg2, TArg3, TArg4}"]/*'/>
        public bool CanResolve<TService, TArg1, TArg2, TArg3, TArg4>(string name, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4)
        {
            return GetEntry<TService, Func<Container, TArg1, TArg2, TArg3, TArg4, TService>>(name, false) != null;
        }

        /// <include file='Container.xdoc' path='docs/doc[@for="Container.CanResolve{TService, TArg1, TArg2, TArg3}"]/*'/>
        public bool CanResolve<TService, TArg1, TArg2, TArg3>(string name, TArg1 arg1, TArg2 arg2, TArg3 arg3)
        {
            return GetEntry<TService, Func<Container, TArg1, TArg2, TArg3, TService>>(name, false) != null;
        }

        /// <include file='Container.xdoc' path='docs/doc[@for="Container.CanResolve{TService, TArg1, TArg2}"]/*'/>
        public bool CanResolve<TService, TArg1, TArg2>(string name, TArg1 arg1, TArg2 arg2)
        {
            return GetEntry<TService, Func<Container, TArg1, TArg2, TService>>(name, false) != null;
        }

        /// <include file='Container.xdoc' path='docs/doc[@for="Container.CanResolve{TService, TArg1, TArg2}"]/*'/>
        public bool CanResolve<TService, TArg1>(string name, TArg1 arg1)
        {
            return GetEntry<TService, Func<Container, TArg1, TService>>(name, false) != null;
        }

        /// <include file='Container.xdoc' path='docs/doc[@for="Container.CanResolve{TService, TArg1, TArg2}"]/*'/>
        public bool CanResolve<TService>(string name)
        {
            return GetEntry<TService, Func<Container, TService>>(name, false) != null;
        }

 

Obviously the links to the documentation aren't gonna work, but other than that it compiles just fine. I will redo my spike and see if it works the way it should. Does it look right to you guys?

Matt

May 11, 2009 at 1:07 AM

I've updated the code in the previous post a few times as I've discovered little bugs with it. It now works really well. I don't actually know how to submit a patch - is it ok if I do it via that post?

Matt

Coordinator
May 11, 2009 at 2:08 PM
I assume you have corresponding unit tests ;)

other than that, it looks good.
I prefer IsRegistered<....> rather than CanResolve, though (as you're looking for a matching registration, basically)

/kzu

--
Daniel Cazzulino | Developer Lead | XML MVP | Clarius Consulting | +1 425.329.3471


On Sun, May 10, 2009 at 10:07 PM, mabster <notifications@codeplex.com> wrote:

From: mabster

I've updated the code in the previous post a few times as I've discovered little bugs with it. It now works really well. I don't actually know how to submit a patch - is it ok if I do it via that post?

Matt

Read the full discussion online.

To add a post to this discussion, reply to this email (funq@discussions.codeplex.com)

To start a new discussion for this project, email funq@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com


May 11, 2009 at 9:04 PM
Strangely, my copy of VS (2008 Professional) couldn't open the unit test project.
I'll rename the methods to "IsRegistered" at my end. Early spikes with my existing project have worked really well with this new code!

From: [email removed]
Sent: Tuesday, May 12, 2009 12:08 AM
To: [email removed]
Subject: Re: Determine if a Type/Name has been Registered [funq:55546]

From: dcazzulino

I assume you have corresponding unit tests ;)

other than that, it looks good.
I prefer IsRegistered<....> rather than CanResolve, though (as you're looking for a matching registration, basically)

/kzu

--
Daniel Cazzulino | Developer Lead | XML MVP | Clarius Consulting | +1 425.329.3471


On Sun, May 10, 2009 at 10:07 PM, mabster <notifications@codeplex.com> wrote:

From: mabster

I've updated the code in the previous post a few times as I've discovered little bugs with it. It now works really well. I don't actually know how to submit a patch - is it ok if I do it via that post?

Matt

Read the full discussion online.

To add a post to this discussion, reply to this email (funq@discussions.codeplex.com)

To start a new discussion for this project, email funq@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com


May 11, 2009 at 10:25 PM
Oops - I stand corrected. It was the Silverlight project that threw the error. I will add some tests today and see how I go!

From: [email removed]
Sent: Tuesday, May 12, 2009 7:05 AM
To: [email removed]
Subject: Re: Determine if a Type/Name has been Registered [funq:55546]

From: mabster

Strangely, my copy of VS (2008 Professional) couldn't open the unit test project.
I'll rename the methods to "IsRegistered" at my end. Early spikes with my existing project have worked really well with this new code!

From: [email removed]
Sent: Tuesday, May 12, 2009 12:08 AM
To: [email removed]
Subject: Re: Determine if a Type/Name has been Registered [funq:55546]

From: dcazzulino

I assume you have corresponding unit tests ;)

other than that, it looks good.
I prefer IsRegistered<....> rather than CanResolve, though (as you're looking for a matching registration, basically)

/kzu

--
Daniel Cazzulino | Developer Lead | XML MVP | Clarius Consulting | +1 425.329.3471


On Sun, May 10, 2009 at 10:07 PM, mabster <notifications@codeplex.com> wrote:

From: mabster

I've updated the code in the previous post a few times as I've discovered little bugs with it. It now works really well. I don't actually know how to submit a patch - is it ok if I do it via that post?

Matt

Read the full discussion online.

To add a post to this discussion, reply to this email (funq@discussions.codeplex.com)

To start a new discussion for this project, email funq@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com


May 11, 2009 at 10:36 PM
Ok, I've had to add a bunch of overloads for non-named registrations. First, here are the tests (only testing the zero-argument overloads right now):
[TestMethod]
public void RegisteredTypeIsRegistered()
{
var container = new Container();
var f1 = new Foo();
container.Register<IFoo>(f1);
Assert.IsTrue(container.IsRegistered<IFoo>());
}
[TestMethod]
public void UnregisteredTypeIsNotRegistered()
{
var container = new Container();
Assert.IsFalse(container.IsRegistered<IFoo>());
}
[TestMethod]
public void RegisteredNamedTypeIsRegistered()
{
var container = new Container();
var f1 = new Foo();
container.Register<IFoo>("Foo", f1);
Assert.IsTrue(container.IsRegistered<IFoo>("Foo"));
}
[TestMethod]
public void UnregisteredNamedTypeIsNotRegistered()
{
var container = new Container();
Assert.IsFalse(container.IsRegistered<IFoo>("Foo"));
}
And here is the code:
/// <include file='Container.xdoc' path='docs/doc[@for="Container.IsRegistered{TService, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6}"]/*'/>
public bool IsRegistered<TService, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6>(string name, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6)
{
return GetEntry<TService, Func<Container, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TService>>(name, false) != null;
}
/// <include file='Container.xdoc' path='docs/doc[@for="Container.IsRegistered{TService, TArg1, TArg2, TArg3, TArg4, TArg5}"]/*'/>
public bool IsRegistered<TService, TArg1, TArg2, TArg3, TArg4, TArg5>(string name, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5)
{
return GetEntry<TService, Func<Container, TArg1, TArg2, TArg3, TArg4, TArg5, TService>>(name, false) != null;
}
/// <include file='Container.xdoc' path='docs/doc[@for="Container.IsRegistered{TService, TArg1, TArg2, TArg3, TArg4}"]/*'/>
public bool IsRegistered<TService, TArg1, TArg2, TArg3, TArg4>(string name, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4)
{
return GetEntry<TService, Func<Container, TArg1, TArg2, TArg3, TArg4, TService>>(name, false) != null;
}
/// <include file='Container.xdoc' path='docs/doc[@for="Container.IsRegistered{TService, TArg1, TArg2, TArg3}"]/*'/>
public bool IsRegistered<TService, TArg1, TArg2, TArg3>(string name, TArg1 arg1, TArg2 arg2, TArg3 arg3)
{
return GetEntry<TService, Func<Container, TArg1, TArg2, TArg3, TService>>(name, false) != null;
}
/// <include file='Container.xdoc' path='docs/doc[@for="Container.IsRegistered{TService, TArg1, TArg2}"]/*'/>
public bool IsRegistered<TService, TArg1, TArg2>(string name, TArg1 arg1, TArg2 arg2)
{
return GetEntry<TService, Func<Container, TArg1, TArg2, TService>>(name, false) != null;
}
/// <include file='Container.xdoc' path='docs/doc[@for="Container.IsRegistered{TService, TArg1, TArg2}"]/*'/>
public bool IsRegistered<TService, TArg1>(string name, TArg1 arg1)
{
return GetEntry<TService, Func<Container, TArg1, TService>>(name, false) != null;
}
/// <include file='Container.xdoc' path='docs/doc[@for="Container.IsRegistered{TService, TArg1, TArg2}"]/*'/>
public bool IsRegistered<TService>(string name)
{
return GetEntry<TService, Func<Container, TService>>(name, false) != null;
}
/// <include file='Container.xdoc' path='docs/doc[@for="Container.IsRegistered{TService, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6}"]/*'/>
public bool IsRegistered<TService, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6>(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6)
{
return GetEntry<TService, Func<Container, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TService>>(null, false) != null;
}
/// <include file='Container.xdoc' path='docs/doc[@for="Container.IsRegistered{TService, TArg1, TArg2, TArg3, TArg4, TArg5}"]/*'/>
public bool IsRegistered<TService, TArg1, TArg2, TArg3, TArg4, TArg5>(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5)
{
return GetEntry<TService, Func<Container, TArg1, TArg2, TArg3, TArg4, TArg5, TService>>(null, false) != null;
}
/// <include file='Container.xdoc' path='docs/doc[@for="Container.IsRegistered{TService, TArg1, TArg2, TArg3, TArg4}"]/*'/>
public bool IsRegistered<TService, TArg1, TArg2, TArg3, TArg4>(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4)
{
return GetEntry<TService, Func<Container, TArg1, TArg2, TArg3, TArg4, TService>>(null, false) != null;
}
/// <include file='Container.xdoc' path='docs/doc[@for="Container.IsRegistered{TService, TArg1, TArg2, TArg3}"]/*'/>
public bool IsRegistered<TService, TArg1, TArg2, TArg3>(TArg1 arg1, TArg2 arg2, TArg3 arg3)
{
return GetEntry<TService, Func<Container, TArg1, TArg2, TArg3, TService>>(null, false) != null;
}
/// <include file='Container.xdoc' path='docs/doc[@for="Container.IsRegistered{TService, TArg1, TArg2}"]/*'/>
public bool IsRegistered<TService, TArg1, TArg2>(TArg1 arg1, TArg2 arg2)
{
return GetEntry<TService, Func<Container, TArg1, TArg2, TService>>(null, false) != null;
}
/// <include file='Container.xdoc' path='docs/doc[@for="Container.IsRegistered{TService, TArg1, TArg2}"]/*'/>
public bool IsRegistered<TService, TArg1>(TArg1 arg1)
{
return GetEntry<TService, Func<Container, TArg1, TService>>(null, false) != null;
}
/// <include file='Container.xdoc' path='docs/doc[@for="Container.IsRegistered{TService, TArg1, TArg2}"]/*'/>
public bool IsRegistered<TService>()
{
return GetEntry<TService, Func<Container, TService>>(null, false) != null;
}
Is it correct to keep the xdoc comment paths the same for the named and unnamed overloads?
Matt
Coordinator
May 12, 2009 at 4:12 PM

Oh boy!

Please take a look at this post http://www.hanselman.com/blog/ExampleHowToContributeAPatchToAnOpenSourceProjectLikeDasBlog.aspx

A patch would definitely be the way to go :). You can create a workitem and attach the patch to it. That would make my life so much easier.

It's OK to point all methods to the same documentation in teh xdoc. That's the beauty of it, you don't have to copy-paste it all over the palce :)

 

Thanks!

May 12, 2009 at 9:01 PM
No worries, Kzu - I'll check it out. Funq's gonna save me a lot of pain in the future so it's only fair I try to save you some. Smile emoticon

From: [email removed]
Sent: Wednesday, May 13, 2009 2:12 AM
To: [email removed]
Subject: Re: Determine if a Type/Name has been Registered [funq:55546]

From: dcazzulino

Oh boy!

Please take a look at this post http://www.hanselman.com/blog/ExampleHowToContributeAPatchToAnOpenSourceProjectLikeDasBlog.aspx

A patch would definitely be the way to go :). You can create a workitem and attach the patch to it. That would make my life so much easier.

It's OK to point all methods to the same documentation in teh xdoc. That's the beauty of it, you don't have to copy-paste it all over the palce :)

Thanks!

May 12, 2009 at 10:22 PM
Aw man, that requires extra stuff on my PC. I'm doing this on my work PC and we don't use svn. Is there a simple, stand-alone diff tool I can use to compare two files and generate a patch from their differences?
The code I posted was purely additive - nothing changed in the existing source so it's really just a matter of copy and paste.
Matt

From: [email removed]
Sent: Wednesday, May 13, 2009 2:12 AM
To: [email removed]
Subject: Re: Determine if a Type/Name has been Registered [funq:55546]

From: dcazzulino

Oh boy!

Please take a look at this post http://www.hanselman.com/blog/ExampleHowToContributeAPatchToAnOpenSourceProjectLikeDasBlog.aspx

A patch would definitely be the way to go :). You can create a workitem and attach the patch to it. That would make my life so much easier.

It's OK to point all methods to the same documentation in teh xdoc. That's the beauty of it, you don't have to copy-paste it all over the palce :)

Thanks!

Coordinator
May 13, 2009 at 12:37 PM

you could use the command-line version of svn

May 14, 2009 at 12:28 AM

Patch uploaded! Quite proud of myself actually - first time I've ever used svn. :) Baby steps!

Coordinator
Oct 2, 2010 at 5:21 AM

where did this patch go, in the end? can't find it here, or in my emails :((((

Oct 2, 2010 at 3:23 PM
Edited Oct 2, 2010 at 3:24 PM

Ugh. Looks like it disappeared when Funq switched from svn to hg - there used to be a "patches" link under Source Code where you could find it. I've long since migrated to Autofac so I don't know if I have the patch anymore either. I will check when I'm back at work in a few weeks.

Coordinator
Oct 2, 2010 at 10:14 PM

no worries :)

we're going with support for WP7 :)