MEF example in Silverlight 4 - silverlight-4.0

Although there are many examples of Silverlight projects using MEF (Managed Extensibility Framework), since the System.ComponentModel.Composition.Packaging.Toolkit package was removed in the version that is shipped inside Silverlight 4, these projects are away from helping to run some basic MEF example.
Some tutorials using the newer API will be very beneficial.
Thanks.

Although I can't point you in the direction of a concrete example, it's quite trivial to start composing parts of your Silverlight 4 application. Given the example:
public partial class MainPage : UserControl, IContext
{
[ImportMany]
public IEnumerable<IPlugin> Plugins { get; set; }
public MainPage()
{
InitializeComponent();
CompositionInitializer.SatisfyImports(this);
Plugins.First().Run(this);
}
public void ShowMessage(string message)
{
textBox1.Text = message;
}
}
public interface IContext
{
void ShowMessage(string message);
}
public interface IPlugin
{
void Run(IContext context);
}
[Export(typeof(IPlugin))]
public class SamplePlugin : IPlugin
{
public void Run(IContext context)
{
context.ShowMessage("Hello World");
}
}
The CompositionInitializer type provides SatisfyImports methods which action a default CompositionContainer which is plugged into a catalog that reads parts from your deployed XAP files. If you want more fine grained control over how the catalog is created, you can always create your own CompositionContainer.
Are there any particular aspects of MEF with Silverlight you are looking for advice on?

I wrote a blog post how you can implement MEF into you Silverlight applictaion see
http://www.arrangeactassert.com/solid-design-principles-using-mef-in-silverlight-and-wpf/

I think this is what you are after.

Related

Calling WCF service with parameter

I am developing a SharePoint addin which has a SharePoint-hosted part and a provider-hosted part. In my provider hosted part, I have a couple of services that install a couple of things like Taxonomy and Search. I use C# CSOM for this. This is the only purpose of the provider-hosted part. When the addin is installed, a AppInstalled Event Triggers which calls a remote event receiver. This remote event receiver should then call my WCF services one by one.
Now to my actual question: I currently use this approach for consuming my services:
var taxBinding = new BasicHttpBinding();
var taxEndpoint = new EndpointAddress(remoteUrl.ToString() + "/Services/TaxonomySetupService.svc");
var taxChannelFactory = new ChannelFactory<ISetupService>(taxBinding, taxEndpoint);
ISetupService taxClient = null;
try
{
taxClient = taxChannelFactory.CreateChannel();
taxClient.SetAppWebUrl(appWebUrl.ToString());
if (!taxClient.IsInstalled())
taxClient.Install();
string logs = taxClient.GetLogs();
((ICommunicationObject)taxClient).Close();
}
catch (Exception ex)
{
if (taxClient != null)
{
((ICommunicationObject)taxClient).Abort();
}
}
ISetupService:
[ServiceContract]
public interface ISetupService
{
string OpenText { get; }
string DoneText { get; }
string AppWebUrl { get; set; }
[OperationContract]
bool IsInstalled();
[OperationContract]
void SetLogComponent(LogList logList);
[OperationContract]
void SetAppWebUrl(string url);
[OperationContract]
void WriteToLog(string message);
[OperationContract]
string GetLogs();
[OperationContract]
void Install();
}
My solution doesn't have to follow this approach though so I am looking for something better. Specifically, I need to pass a ClientContext object into my ISetupService constructor. What would be the simplest approach here?
Option 1 - Lazy Injectable property
Why in the constructor? Why not have a Lazy Injectable property?
internal IClientContext Context
{
get { return _Context ?? (_Context = SomeStaticHelper.Context); }
set { _Context = value; } // Allows for replacing IContext for unit tests
} private IClientContext _Context;
public class SomeStaticHelper
{
public static IContext Context { get; set; } // Set this in global.asax
}
Pro: No additional library
Pro: Your can replace IContext in Unit Tests easily (use InternalsVisibleTo)
Con: Class is coupled to SomeStaticHelper for compile.
Con: Doing this for one class is nice, but doing this for 100 classes is not so nice.
Option 2 - Dependency Injection
Or you could use straight up dependency injection, such as Autofac.
http://docs.autofac.org/en/latest/getting-started/
Pro: The class is decoupled and the dependency is injected.
Pro: If you have many classes that need dependency injection, this is the way to go because the overhead is now a couple class files instead of a property in every class file.
Con: You have to add a framework to your code.
Con: You now need more code and other objects to configure the dependency injection.
Use option 1 for small projects that have little need for dependency injection. I think this is the simplest approach here.
Use option 2 for large projects that use DI all the time.

ASP.NET MVC 4 Background operations

I am looking for nice and elegant architectural solution for ASP.NET MVC 4 Background operations.
My goal is developing some world that lives its own life and clients can only interact with it. For now let's say that it will be a simple clock and clients can watсh on it.
Now I have WebBackrounder + SignalR packages.
WebBackrounder:
[assembly: PostApplicationStartMethod(typeof(WebBackgrounderSetup), "Start")]
[assembly: ApplicationShutdownMethod(typeof(WebBackgrounderSetup), "Shutdown")]
namespace LibcanvasStudy.App_Start
{
public static class WebBackgrounderSetup
{
static readonly JobManager _jobManager = CreateJobWorkersManager();
public static RedrawJob RedrawJob { get; private set; }
public static void Start()
{
_jobManager.Start();
}
public static void Stop()
{
_jobManager.Stop();
}
public static void Shutdown()
{
_jobManager.Dispose();
}
private static JobManager CreateJobWorkersManager()
{
RedrawJob = new RedrawJob(TimeSpan.FromSeconds(1));
var manager = new JobManager(new[] { RedrawJob }, new JobHost());
return manager;
}
}
RedrawJob while its execution rise event and SignalR hub catches it:
public class CanvasHub : Hub
{
public CanvasHub()
{
if (WebBackgrounderSetup.RedrawJob != null)
WebBackgrounderSetup.RedrawJob.Executing += (sender, args) => Request(args);
}
public void Request(RedrawEventArgs eventArgs)
{
Clients.All.redraw(...);
}
}
I have one main problem for now - How I can dynamicaly add and remove jobs from my JobManager?
Also I don't like this job-event system, it's a little bit awkwardly for me. Any proposal?
What darin says is correct, but it can be worked around. For example what I do for these kind of scenarios is to have a internal WCF service that handles all jobs, you call it from the schedular or workflow engine using net.tcp or memory pipe. This way you benefit from all IIS sugar coating. And dont need to marshal your threads and error handing.
Second, implement some kind of event bus to decouple SignalR and your domain logic.
I have written this little lib that proxies between domain events and SignalR
https://github.com/AndersMalmgren/SignalR.EventAggregatorProxy
Install using nuget
Install-Package SignalR.EventAggregatorProxy
Please look at the wiki for the few easy steps required to hook it up
https://github.com/AndersMalmgren/SignalR.EventAggregatorProxy/wiki
For a super lightweight in process event bus look at Caliburn.Micros EventAggregator
http://nuget.org/packages/Caliburn.Micro.EventAggregator/
What do you think about using this code in any part of MVC app?
IHubContext hub = GlobalHost.ConnectionManager.GetHubContext<CanvasHub>();
hub.Clients.All.redraw(redrawData);

How to use dynamic module loading in an onion architecture using MVC4 as frontend

I'm trying to wrap my head around dependency injection in the Onion Architecture, I've found this solution which uses a dependency resolution layer around the onion. But there is so much going on that I'm completely lost.
So I setup a project to try it out. I like to start off simple, so a simple log entry on a (MVC) controller method would be a good start.
I'd like to use Dynamic Module Loading (kernel.Load("*.dll");) since it comes recommended from the Ninject wiki.
My solution looks like this: (For now)
Solution
- Core.Services
- Infrastructure.Logging
- DependencyResolution
- UI.MVC (default internet template)
I'd like to follow the guides lines for dependency resolution outlined here.
Ilogger
namespace Core.Services
{
public interface ILogger
{
void Log(string message);
}
}
Logging Implementation
namespace Infrastructure.Logging
{
public class DebugLogger : ILogger
{
public void Log(string message)
{
Debug.WriteLine(message);
}
}
}
Dependency Resolution
namespace DependencyResolution
{
public class TestModule : NinjectModule
{
public override void Load()
{
Bind<ILogger>().To<DebugLogger>();
}
}
}
What I want to accomplish
UI
namespace UI.MVC.Controllers
{
public class HomeController : Controller
{
private readonly ILogger _logger;
public HomeController(ILogger logger)
{
_logger = logger;
}
public ActionResult Index()
{
ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";
_logger.Log("It works!");
return View();
}
}
}
I need to run kernel.Load("*.dll"); somehow and I need to setup my MVC to use DI. I'm just now sure how since the UI cannot know about the Dependency Resolution layer.
Your DI container should be composed somewhere. This place is called the composition root and is the outermost layer. In your case that would be the ASP.NET MVC application. So saying that it should not know about the DI simply doesn't make sense. The Ninject.MVC3 package comes with a custom dependency resolver implementation that gets plugged into the application and you will get automatic DI in your controllers.

Using PostSharp OnExceptionAspect across mulit projects

Good afternoon everyone,
I am trying to use the example "Aspect Oriented Programming Using C# and PostSharp" by Reza Ahmadi
http://www.codeproject.com/Articles/337564/Aspect-Oriented-Programming-Using-Csharp-and-PostS and dnrTV http://dnrtv.com/dnrtvplayer/player.aspx?ShowNum=0190 for the exception handling. Everything works great if the "OnExceptionAspect" is in the same project/assembly, however the event does not work if it I move the class to it own dll.
[assembly: ExceptionAspect (AttributePriority = 1)]
[assembly: ExceptionAspect(AttributePriority = 2, AttributeExclude = true, AttributeTargetTypes = "HpsErp.Common.AspectObject.*")]
namespace AspectObject
[Serializable]
public class ExceptionAspect : OnExceptionAspect
{
public override void OnException(MethodExecutionArgs args)
{
Trace.TraceError("{0} in {1}.{2}",
args.Exception.GetType().Name,
args.Method.DeclaringType.FullName,
args.Method.Name);
if (args.Instance != null)
{
Trace.TraceInformation("this={0}", args.Instance);
}
foreach (ParameterInfo parameter in args.Method.GetParameters())
{
Trace.TraceInformation("{0}={1}", parameter.Name,
args.Arguments[parameter.Position] ?? "null");
}
}
I also created a class in the external dll for "Timing" and it works great if I add a custom attribute to the class.
namespace AspectObject
[Serializable]
[MulticastAttributeUsage(MulticastTargets.Method)]
public class TimingAspect : OnMethodBoundaryAspect
{
[NonSerialized]
Stopwatch _StopWatch;
public override void OnEntry(MethodExecutionArgs args)
{
_StopWatch = Stopwatch.StartNew();
base.OnEntry(args);
}
public override void OnExit(MethodExecutionArgs args)
{
Console.WriteLine(string.Format("[{0}] took {1}ms to execute",
new StackTrace().GetFrame(1).GetMethod().Name,
_StopWatch.ElapsedMilliseconds));
base.OnExit(args);
}
Using AspectObject;
namespace MyApp
{
public class Car
{
[TimingAspect]
private void Drive()
{
//...
}
}
}
In the end, I am hoping to have this is multi dlls so that I can reuse it ie: wcf.
Thanks for any and all help...
James
You can access your aspects if they are stored in a separate DLL.
I always create a DLL class project called Aspects. In the projects I want AOP, I add a reference to that dll class. Then decorate your methods/class/assembly like you normally do.
https://github.com/sharpcrafters/PostSharp-Toolkits <-- good examples
http://researchaholic.com/tag/postsharp/ <-- some more examples, just uploaded an example

Castle Windsor dependancy injection of nHibernate ISession into WebForms

I was wondering how to wire up Castle Windsor in WebForms.
I'm assuming that the second line wires up the controllers in MVC:
// Initialize Windsor
IWindsorContainer container = new WindsorContainer().Install(FromAssembly.This());
ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(container.Kernel));
How do I then wire up WebForms in ASP.NET?
I had a project which I have modified into an identical WebForms setup. Everything works up until the point where I want Castle Windsor to inject ISession into the ASPX page. It simply doesn't and I am under the assumption that the second line of code, above, is what does it for MVC controllers.
I have this in my nHibernate installer, in teh same place on both projects:
container.Register(Component.For<ISession>()
.LifeStyle.PerWebRequest
.UsingFactoryMethod(kernel => kernel.Resolve<ISessionFactory>().OpenSession()));
I had originally assumed this would do it but it is not the case.
I have been stuck on this for days and with very little official documentation on this I am close to ripping my hair out, what's left of it.
I do know the ASP.NET WebForms are not specifically designed to work with dependancy injection but Ninject have done it, albeit with a little hacking, if I can confirm that Castle Windsor is not compatible and/or will no longer support WebForms I will move to something else.
I managed to stuff Castle Windsor in to WebForms using the code here How to use Castle Windsor with ASP.Net web forms? It uses an an attribute to mark where a dependency should be injected in the a WebFrom.
I then used an MVP pattern. Each WebForm had a presenter
public partial class TestPage : UserControl, IShowTestPage
{
[Inject]
public TestPagePresenter Presenter { get; set; }
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack) return;
this.Presenter.OnViewInitialized();
}
public string TestMessage
{
get { return litTestMessage.Text; }
set { litTestMessage.Text = value; }
}
}
As the Presenter is resolved form the container, it is then back to normal for wiring up the dependencies
public interface IShowTestPage {
string TestMessage { get; set;}
}
public class TestPagePresenter {
private ISession session;
public TestPagePresenter(ISession session) {
this.session = session;
}
private IShowTestPage view;
public IShowTestPage { set { view = value; } }
public void OnViewInitialized {
TestMessage = session.Query("some database query");
}
}
My solution was based on a great article by Billy McCafferty