Dynamic loading - My first LINQ sentence

U

Udi

Just wanted to get your feedbacks -
Given a folder, I'd like to search for all dlls in it and load (and
instantiate) only the ones containing types implemeinting a desired
interface (IAnalyzer). I came up with this LINQ sentence, however I'm
not sure this is the best I can do since I'm newbie with LINQ.
Any suggestions?
Thanks,
Udi.

//searching, loading and instantiating...
IList<IAnalyzer> items = (from string dll in
Directory.GetFiles("<the given
path>", "*.dll", SearchOption.AllDirectories)
from Type type in
Assembly.ReflectionOnlyLoadFrom(dll).GetExportedTypes()
where type.IsClass &&
type.GetInterface("IAnalyzer") != null
select (IAnalyzer)
(Assembly.LoadFile(dll).CreateInstance(type.ToString(), true))).ToList
();

// working with the Analyzers...
foreach (IAnalyzer item in items)
{
Console.WriteLine(item.Name);
}
 
P

Peter Duniho

Udi said:
Just wanted to get your feedbacks -
Given a folder, I'd like to search for all dlls in it and load (and
instantiate) only the ones containing types implemeinting a desired
interface (IAnalyzer). I came up with this LINQ sentence, however I'm
not sure this is the best I can do since I'm newbie with LINQ.
Any suggestions?

My main suggestion: don't use LINQ unless it really adds something
useful to the code.

I mean, I suppose it's an interesting exercise to convert all of your
logic to LINQ, if you're trying to learn LINQ. But what does wrapping this:

IList<IAnalyzer> items = new List<IAnalyzer>();

foreach (string dll in Directory.GetFiles("<the given path>",
"*.dll", SearchOption.AllDirectories))
{
foreach (Type type in
Assembly.ReflectionOnlyLoadFrom(dll).GetExportedTypes())
{
if (type.IsClass && type.GetInterface("IAnalyzer") != null)
{

items.Add(Assembly.LoadFile(dll).CreateInstance(type.ToString(), true));
}
}
}

foreach (IAnalyzer item in items)
{
Console.WriteLine(item.Name);
}

....in LINQ do to improve the code? It's practically the same number of
characters, and IMHO is at least as clear.

That said, the LINQ you posted looks fine to me. Assuming it does what
you want, I don't see any need to change it. Note, of course, that a C#
struct can implement an interface, but you are only examining classes.
That may or may not be intentional.

Pete
 
S

Simon Woods

My main suggestion: don't use LINQ unless it really adds something
useful to the code.

Hi Peter, can I get your views on this (and anyone elses for that matter)?

It seems to me that behind this suggestion is the implicit assumption of
serial/procedural coding. If you use LINQ by default are you not moving
away from that paradigm since you are working declaratively at a
slightly higher level of abstraction.

I know that there are issues of over-engineering, and only doing what
you need to do etc etc, but I wonder whether the issue is one of a
programming paradigm shift? Thus, you only do what you need to etc but
the tools you use abstract away, for example, from the question of
serial or parallel.

.... or perhaps I have been suckered by MS's marketing machine ...!

Thx

Simon
 
J

Jeff Johnson

... or perhaps I have been suckered by MS's marketing machine ...!

Coming from the perspective of someone who has never touched LINQ at all
(and therefore probably isn't qualified to judge), I must say that that is
my EXACT perspective on LINQ: Marketing
hype/try-it-it's-the-latest-and-greatest-thing-and-we-needed-something-new-to-sell-the-next-version-of-Visual-Studio.
Take my opinion with a grain of salt, though, because this is exaclty how I
felt about XML for years. (But in truth, XML really was presented as a magic
bullet when it wasn't.)
 
S

Simon Woods

Coming from the perspective of someone who has never touched LINQ at all
(and therefore probably isn't qualified to judge), I must say that that is
my EXACT perspective on LINQ: Marketing
hype/try-it-it's-the-latest-and-greatest-thing-and-we-needed-something-new-to-sell-the-next-version-of-Visual-Studio.
Take my opinion with a grain of salt, though, because this is exaclty how I
felt about XML for years. (But in truth, XML really was presented as a magic
bullet when it wasn't.)

.... although is there not a greater push across the mainstream software
industry toward functional programming as a means of harnessing
multi-core developments?

... or maybe it has just entered my awareness!
 
P

Peter Duniho

Simon said:
[...]
My main suggestion: don't use LINQ unless it really adds something
useful to the code.

Hi Peter, can I get your views on this (and anyone elses for that matter)?

It seems to me that behind this suggestion is the implicit assumption of
serial/procedural coding. If you use LINQ by default are you not moving
away from that paradigm since you are working declaratively at a
slightly higher level of abstraction. [...]

I'm not sure it's a "higher level". It's certainly a slightly different
way to represent the logic. But inasmuch as much of LINQ (and certainly
the parts your original example is using) is simply a plain syntactical
search-and-replace, I don't see how I would call it "higher level". To
me, "higher level" implies that one is able represent a particular
operation in a more concise and/or more expressive way.

More concise should be obvious. We see this even in relatively simple
"high level languages", where control or looping statements get
translated into much more wordy, but much-less-obvious equivalents in
machine code.

More expressive is not always more concise (but IMHO usually is). But
it does mean that the "higher level" feature allows you to _express_ the
solution to a problem in a way that is closer to the real-world
framework of the problem.

LINQ shines in the latter way when you're doing things that are
naturally more like database queries than they are like plain old
iterative processing. You wind up being able to express the query
itself in a language that has a similar structure to that used for the
database, rather than having to wrap up the database language in some
non-database syntax (e.g. filling a .NET data structure with SQL query
strings).

An example of where LINQ can add a lot of benefit in both the "more
concise" and "more expressive" way is when using the System.Xml.Linq
namespace, where the design of the types in the namespace has been
carefully thought out to work very well with declarative-like code using
LINQ. The operations aren't database-like, but inasmuch as XML tends to
be a sort of declarative data structure-oriented thing, having a
declarative way to generate and process XML can be very useful.

In this newsgroup especially, I have seen a LOT of LINQ code examples
that were actually _less_ expressive and more difficult to write and
understand than the non-LINQ code would have been. They were written
just for the sake of implementing something in LINQ, rather than because
LINQ was actually improving the code somehow.

The code example you posted is in a sort of middle ground. There are at
least a couple of places where using LINQ may be viewed as beneficial:
being able to use "where" to filter the results of the previous
enumeration, and using "select" to essentially "project" those results
into a new form (the actual instances you'll use).

But on the other hand, LINQ is IMHO obfuscating other aspects of the
code: even the first "from" clause is potentially a little awkward, and
having the second one following the first is not expressive at all,
unless the reader is already a strong LINQ user. Otherwise, one might
have to stop and think "a normal 'from' pulls from an enumeration
following the 'from', but here we have a 'from' pulling from an
enumeration preceding the 'from'". And even then, that's not what's
really going on; the second "from" really does pull from an enumeration
that follows it, but that enumeration depends on the previous "from" in
a way that may not be immediately or directly apparent to the casual reader.

Within LINQ, that's a perfectly natural way to express things, but it
does not IMHO make the code more obvious to the casual reader.

Another issue IMHO is that you are using the LINQ expression
immediately, and converting it directly to a list. This does come up,
of course...it's not like it's a patently bad thing to do. But I feel
that LINQ is at its best when you're actually using it to declare
_queries_. If the query being declared has to be immediately executed
for it to be of any practical use, and the LINQ isn't otherwise adding
something to the expressiveness of the code, for me that's a sign that
perhaps LINQ wasn't really the appropriate tool for the job.

Anyway, that's just a very long way of saying: LINQ can be cool and fun
to use, but don't get carried away. The "old ways" still work fine, and
in many cases are a better way to present the algorithm you're implementing.

I do recognize that there are times when making a paradigm shift -- e.g.
using a completely different syntax to represent a given solution -- can
lead to a perceptive benefit that allows you to come up with a whole new
approach to solving a problem that is better in some way than the
previous approach. But, if someone can come in and trivially rewrite a
LINQ expression as a couple of "foreach" loops with an "if" and an
"Add()", the LINQ probably isn't adding much to the problem.

Just my two cents. And you know how much that's worth these days. :)

Pete
 
Top