Yes, I have. Load of each assembly is approximately 50ms - 300ms
depending on the number of classes and on how "warm" the OS is.

Calling assembly.GetTypes() is 20ms to 200ms depending on the number
of types in the assembly and on how my computer feels

Trying to go through all relevant assemblies and scan I get:

Loaded 14 assemblies for component scanning in 1115ms (loading all the
assemblies I need components for)
Created 223 components for types in 14 assemblies in 4232ms (this
number is inflated by the time spent loading dependent assemblies -
below)
Loaded 34 dependent assemblies from file system in 2227ms (this is a
count of automatically loaded assemblies from before I start created
components until after)

The number of assemblies loaded is higher than the number of component
assemblies because even if I don't need components for that assembly,
calling GetTypes() on it will force load of all referenced assemblies.
So, for assembly MyApp.Web, calling GetTypes will automatically load
System.Web, System.Web.ApplicationServices, DevExpress.XXX, etc.

Performance aside, it's mainly a LOE concern to make sure we correctly
identify all of the types that require DI.

On Sep 14, 1:23 am, Krzysztof Koźmic <[email protected]>
wrote:
> You can come up with any convention for that, not just based on
> attribute, but for example based on name as well
> (Name.EndsWith("ViewModel"))
>
> scanning assemblies is usually relatively fast. Have you measured it?
>
> Krzysztof
>
> On 14/09/2011 12:27 AM, Jeff N wrote:
>
>
>
>
>
>
>
> > It would be simpler...but it would not perform better since the line
> > below would force this assembly and all referenced assemblies to be
> > loaded up into memory right at startup and would add the cost of
> > reflecting over all types in that assembly.
>
> > I could have the LCL check for a [Component] attribute and only
> > register if present...but that's still a major breaking change and
> > would require locating and annotating hundreds of types.
>
> >  From a design standpoint I understand that it's desirable to have
> > components registered up front....but having to explicitly declare
> > every kind of component you want kind of adds a lot of overhead I
> > think (not just in terms of performance).
>
> > On Sep 13, 3:59 am, Krzysztof Koźmic<[email protected]>
> > wrote:
> >> If you already have an attribute
>
> >> [NotifyPropertyChanged]
>
> >> Why are you not using this information to register those types upfront.
> >> You have all the information you need.
>
> >> Container.Register(Classes.FromThisAssembly.Where(t=>
> >> HasTheAttribute(t).Configure(HoweverYouWant));
>
> >> Wouldn't it be nicer and simpler? Not to mention it performs better and
> >> is easier to diagnose too.
>
> >> I really think you're abusing LCL here.
>
> >> Krzysztof
>
> >> On 08/09/2011 8:33 AM, Jeff N wrote:
>
> >>> The goal for my lazy loader is never to resolve services (in the
> >>> semantic sense of the word service). Those are always interfaces with
> >>> internal implementing classes (to avoid accidental directl
> >>> instantiation)...so they are (and must be) explicitly registered in
> >>> the container at startup.
> >>> It's only for proxy/interception support that the lazy loader is
> >>> really necessary. Let's take the example of my search args class. The
> >>> proxy automatically implements INotifyPropertyChanged....but do I
> >>> really need/want to do the busy work of registering all of these
> >>> simple classes as components? I feel like not... Plus let's say a
> >>> developer that doesn't really know anything about DI to interception,
> >>> but does know to add [NotifyPropertyChanged] wants to create a new
> >>> class. Should they really need to go into the Bootstrapper and
> >>> register it? Or add it to a white list? It seems kind of unnecessary
> >>> in terms of friction...
> >>> Plus, on a completely unrelated note, registering all these types for
> >>> proxying means startup of the client application will slow down
> >>> substantially. Loading up all those assemblies where the types live
> >>> (like 10 of them) adds 2 or 3 seconds to startup. If I scan the
> >>> assemblies for types annotated with [Component] attribute or try to
> >>> register all types in the assemblies, startup performance becomes even
> >>> (much much) worse.
> >>> So back to your point...in terms of white listing...adding all those
> >>> components to be proxies to a whitelist is kind of a big friction
> >>> point from a development standpoint.
> >>> I hope I've expressed my concern clearly. Let me know if not.
> >>> Thanks.
> >>> On Sep 7, 6:06 pm, Krzysztof Koźmic<[email protected]>
> >>> wrote:
> >>>> I agree the loader is fragile and sooner or later something will fall
> >>>> through the cracks with this approach.
> >>>> What if instead of blacklisting types (thou shall not be resolved) you
> >>>> give it a whitelist or a whitelisting predicate.
> >>>> Only resolve types from "Foo.Services" namespace, or similar.
> >>>> In general that's the goal for using lazy component loaders, to narrow
> >>>> down their scope as much as possible, rather than making it a catch-all.
> >>>> What is the goal of your lazy component loader?
> >>>> Krzysztof
> >>>> On 08/09/2011 2:32 AM, Jeff N wrote:
> >>>>> Yes, that does work (filtering the service at the LazyComponentLoader
> >>>>> layer)....and that's what I've done in the interim to test other
> >>>>> things:
> >>>>> private static readonly Type[] ExcludedTypes = new[] { typeof(object),
> >>>>> typeof(ControllerBase), typeof(Person) };
> >>>>> if (ExcludedTypes.Contains(serviceType))
> >>>>> {
> >>>>>       return null;
> >>>>> }
> >>>>> in the lazy component loader.
> >>>>> But, I'm really concerned about having to identify all the places that
> >>>>> are bad candidates for lazy loading (there are literally hundreds of
> >>>>> places I'd need to check). Further, I might run across an assembly
> >>>>> that isn't visible to my loader....so essentially the loader becomes a
> >>>>> god class.
> >>>>> If you can bake in some way of controlling the behavior, I'd really
> >>>>> appreciate it. If something is baked in, I guess it would have to be
> >>>>> done at the Kernel itself, not in the loader, right? Because even if
> >>>>> my loader changes it's behavior to ignore optional dependencies, the
> >>>>> other loaders might not know that I want to do so (LazyOfTLoader,
> >>>>> DelegateFactoryLoader, etc.)...
> >>>>> I know it was a bug, but in my thinking, the old behavior really makes
> >>>>> more logical sense - lazy load something only when it's really
> >>>>> necessary....but of course I can appreciate the opposite perspective
> >>>>> too.
> >>>>> Thanks.
> >>>>> Jeff
> >>>>> On Sep 7, 9:05 am, Krzysztof Koźmic<[email protected]>
> >>>>> wrote:
> >>>>>> What about adding some filtering to your lazy component loader?
> >>>>>> WIth this example you gave here I suspect you would never want Person 
> >>>>>> as
> >>>>>> a service anyway, hence applying some filtering based on structure 
> >>>>>> might
> >>>>>> solve that.
> >>>>>> - if requested type is in Acme.Services resolve it
> >>>>>> - otherwise (and I suppose Person would be in Acme.Domain or similar
> >>>>>> namespace) skip it
> >>>>>> I don't think we have a setting to disable it currently, although if 
> >>>>>> the
> >>>>>> above does not solve that for you I might look into introducing some 
> >>>>>> way
> >>>>>> of controlling that behaviour...
> >>>>>> HTH,
> >>>>>> Krzysztof
> >>>>>> On 07/09/2011 10:55 PM, Jeff N wrote:
> >>>>>>> That will solve the issue with MVC Controllers...but there are tons of
> >>>>>>> other places that rely on more intelligent setting.
> >>>>>>> For example:
> >>>>>>> public class SearchArgs
> >>>>>>> {
> >>>>>>>          private Person _personToSearchFor;
> >>>>>>>          public Person PersonToSearchFor
> >>>>>>>          {
> >>>>>>>               get { return _personToSearchFor; }
> >>>>>>>               set
> >>>>>>>               {
> >>>>>>>                      if (value != _personToSearchFor)
> >>>>>>>                      {
> >>>>>>>                             // do some relevant stuff: this breaks now
> >>>>>>> because it's automatically set to an empty, default instantiation of
> >>>>>>> person as soon as the args is resolved.
> >>>>>>>                      }
> >>>>>>>               }
> >>>>>>>          }
> >>>>>>> }
> >>>>>>> Is there no way I can inherit from the DefaultKernel and disable this
> >>>>>>> globally? This completely prevents me from upgrading.
> >>>>>>> Thanks.
> >>>>>>> On Sep 7, 3:01 am, Krzysztof Koźmic<[email protected]>
> >>>>>>> wrote:
> >>>>>>>> Ignore all base-class properties on Controllers when registering
> >>>>>>>> Krzysztof
> >>>>>>>> On 07/09/2011 1:41 PM, Jeff N wrote:
> >>>>>>>>> I understand that in Windsor 3 the design was changed so that 
> >>>>>>>>> optional
> >>>>>>>>> dependencies try to get resolved via an ILazyComponentLoader
> >>>>>>>>> I have a basic ILazyComponentLoader that does
> >>>>>>>>> Component.For(serviceType).Named(key)
> >>>>>>>>> This change breaks a TON of things in the solution, including all
> >>>>>>>>> ASP .NET MVC controllers (since an object property type (Model) on 
> >>>>>>>>> the
> >>>>>>>>> ControllerBase class is now injected with the wrong type.
> >>>>>>>>> Any suggestions on how to work around this? Essentially I just want 
> >>>>>>>>> to
> >>>>>>>>> revert to the old behavior by which optional dependencies are not
> >>>>>>>>> lazily loaded. Is there any way I get get the dependency being
> >>>>>>>>> resolved in context of my lazy component loader, so I can check if
> >>>>>>>>> it's optional and return null if true?
> >>>>>>>>> Thanks.

-- 
You received this message because you are subscribed to the Google Groups 
"Castle Project Users" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/castle-project-users?hl=en.

Reply via email to