For my Twitter / Facebook sync app, after some good input from Scott Hanselman, has been shifted to a plug-in architecture.
Seems easy right? Not so much. My ghetto, non-extendable way was so much easier and hack-ish.
Here is the LINQ for getting the assemblies.
statusUpdates =
(from file in Directory.GetFiles(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "plugins"), "*.dll")
let a = Assembly.LoadFrom(file)
from t in a.GetTypes()
where !t.IsAbstract && t.BaseType == typeof(StatusUpdate)
select (StatusUpdate)Activator.CreateInstance(t, credentials))
.ToList();
Same code, but in traditional context.
string[] filesToTest = Directory.GetFiles(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "plugins"), "*.dll");
foreach (string file in filesToTest)
{
Assembly a = Assembly.LoadFrom(file);
foreach (Type t in a.GetTypes())
{
if (!t.IsAbstract && t.BaseType == typeof(StatusUpdate))
{
statusUpdates.Add((StatusUpdate)Activator.CreateInstance(t, credentials));
}
}
}
So a few things I learned about doing this.
- You can't have the abstract in the same assembly you're loading. I had the credentials as an internal var in the abstract and was lazy. This little bit of laziness caused me a solid hour of trial and error getting this to work properly.
- If you create a plug-in system, your plug-in's damn well better work like everyone else's. Right now there is a fatal flaw with the application's credentials. I have no easy way for lets say, my mom, to update their user names and passwords. This means credentials are compiled into the app which is no good. No longer dynamic.
- I have to tweak the Facebook Developer Toolkit slightly, the login form shows when it really shouldn't.
- I need to get the beta of ReSharper since the non-c# 3.0 features underlines are pissing me off.
- I have to get the events to fire off asynchronously.
Also I did a prebuild and postbuild event for this project which made me feel like a sys-admin
Prebuild
if not exist "$(TargetDir)Plugins" mkdir "$(TargetDir)Plugins"
Postbuild
move "$(SolutionDir)StatusSync.Plugins\bin\$(ConfigurationName)\StatusSync.Plugins.*" "$(TargetDir)plugins"
move "$(SolutionDir)StatusSync.Plugins\bin\$(ConfigurationName)\Facebook.*" "$(TargetDir)plugins"