I have been looking at creating a common logging library for the company I work for, based on a blog by Daniel Cazzulino. so we can switch one out for another without to much disruption.
The first library I looked to use is log4net, but I cannot work out how or where you would setup a call to the XmlConfigurator.
I have tried adding an assembly on the project being logged, which kind of defeats the object of the exercise I feel, but that doesn't appear to work any way.
I have tried adding it as an assembly of the log4net Logging library, but that doesn't appear to work.
I have also tried calling log4net.Config.XmlConfigurator.Configure(); from the TraceManager.Get method, but all the log options (IsDebugEnabled, IsWarnEnabled, ...) are disabled.
public partial class TracerManager : ITracerManager
{
/// <summary>
/// Gets a tracer instance with the specified name.
/// </summary>
public ITracer Get(string name)
{
log4net.Config.XmlConfigurator.Configure();
var logger = LogManager.GetLogger(name);
return new Log4NetAdapter(logger);
}
/// The rest
}
Do I need to do something else?
Does the app config need to be in in the logging library?
[Edit 1]
Feel very silly....
I'd added [assembly: XmlConfigurator(Watch = true)] to my Logging.Log4Net library, but I wasnt instantiating the TracerManager in my application on the tests I was performing... ID-10Tango issue
I'd added [assembly: XmlConfigurator(Watch = true)] to my Logging.Log4Net library, but I wasnt instantiating the TracerManager in my application on the tests I was performing...
ID-10Tango issue
Related
I'm trying to debug an assembly import issue on a WPF app that uses MEF to load some plugins and looking for ideas to solve this particular exception:
More than one export was found that matches the constraint:
ContractName MarkPad.Contracts.ISpellingService
RequiredTypeIdentity MarkPad.Contracts.ISpellingService
There is only one assembly that references the plugin of concerndirectly as part of an autofac registration of it (code snippet at the very end).
[ImportingConstructor]
public SpellCheckPlugin(
IPluginSettingsProvider settingsProvider,
ISpellingService spellingService,
ISpellCheckProviderFactory spellCheckProviderFactory)
There is only 1 implementation of ISpellingService
[Export(typeof(ISpellingService))]
public class SpellingService : ISpellingService
This is an open source Code52 project on github.
The plugin import is:
[ImportMany]
IEnumerable<IPlugin> plugins;
What I've tried so far:
This and this blog post make reference to using [ImportMany(AllowRecomposition = true)] but that also doesn't seem to help.
Other discussions I found mention setting the 'Copy Local' to false, but because it's actually used in registration code that's not an option, as it doesn't end up in the output folder.
Any ideas?
The registration code referencing the plug-in
builder.RegisterType<SpellingService>().As<ISpellingService>()
.SingleInstance()
.OnActivating(args =>
{
var settingsService = args.Context.Resolve<ISettingsProvider>();
var settings = settingsService.GetSettings<SpellCheckPlugin.SpellCheckPluginSettings>();
args.Instance.SetLanguage(settings.Language);
})
Solution
The problem was a bug where the current assembly via GetExecutingAssembly was being used in the PluginManager() as one of the catalog entries in the AggregateCatalog being supplied to the CompositionContainer.
var catalog = new AggregateCatalog();
// This was causing the composition to detect additional imports
catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
This bug came about from extracting out the services/plug-ins into their own assemblies, which were originally part of the core MarkPad assembly.
Credit goes to #shiftkey and this patch.
Extra Improvements
As part of this patch there was some extra clean-up that might be useful to support this answer.
Since the SpellCheckPlugin took interfaces, the exports were simply moved to the interfaces themselves not the concrete types.
[ImportingConstructor]
public SpellCheckPlugin(
IPluginSettingsProvider settingsProvider,
ISpellingService spellingService,
ISpellCheckProviderFactory spellCheckProviderFactory)
Adding Export on Interfaces instead
[InheritedExport]
public interface ISpellCheckProviderFactory
// and
[InheritedExport]
public interface ISpellingService
Removing concrete exports
[Export(typeof(ISpellingService))]
public class SpellingService : ISpellingService
// and
[Export(typeof(ISpellCheckProviderFactory))]
public class SpellCheckProviderFactory : ISpellCheckProviderFactory
OK, now I'm really confused.
I originally had this problem, which is, according to posters, an issue with the version of Castle.DynamicProxy that's ILMerged into the latest Rhino.Mocks library. It has, according to several authorities on the subject, been fixed in the latest Castle, but that library has not made it into a new Rhino.Mocks. Most people are saying "just download the Rhino source and the latest Castle and build your own version".
So, I did exactly that; I grabbed a ZIP of the Rhino trunk source from Ayende's GitHub, opened it up, and built it. Then, like a good little TDDer, I created a unit test to make sure my changes worked (because the latest Castle folds DynamicProxy into Core, requiring some significant referencing changes):
[Test]
public void MockOfInterfaceMethodWithInterfaceGTR()
{
var mock = mocks.DynamicMock<ITestRestrictedInterface>();
Assert.NotNull(mock);
Expect.Call(mock.TestMethod(new Object2())).IgnoreArguments().Return(5);
mocks.ReplayAll();
Assert.AreEqual(5, mock.TestMethod(new Object2()));
}
...
internal interface ITestGenericInterface<TRest> where TRest:IObject1
{
int TestMethod<T>(T input) where T : TRest;
}
internal interface ITestRestrictedInterface:ITestGenericInterface<IObject2> { }
internal interface IObject1 { }
internal interface IObject2:IObject1 { }
internal class Object2:IObject2 { }
The result, when run in my own production code with the latest released Rhino? Failure with the following message:
System.TypeLoadException : Method 'TestMethod' on type
'ITestRestrictedInterfaceProxy83ad369cdf41472c857f61561d434436' from
assembly 'DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral,
PublicKeyToken=null' tried to implicitly implement an interface method
with weaker type parameter constraints.
...However, when I copy and paste this test into a fixture in the Rhino.Mocks.Tests project, without making any changes to referenced libraries, the test PASSES. I have made zero changes to the downloaded source. I have made ZERO changes to the test method and related interfaces/objects on both sides. I built a new Rhino.Mocks DLL (without IL-merging the Castle libs) and copied it with Castle libs back to my production solution, re-ran the test, and it still fails with the same message.
WTF?
I'm not a Castle expert nor compiler guru, but I believe the issue is a little bit of magic that is hidden inside the RhinoMocks.Tests assembly:
From https://github.com/ayende/rhino-mocks/blob/master/Rhino.Mocks.Tests/TestInfo.cs
using System.Runtime.CompilerServices;
using Rhino.Mocks;
[assembly: InternalsVisibleTo(RhinoMocks.StrongName)]
And for completeness sake, RhinoMocks.StrongName is defined as:
/// <summary>
/// Used for [assembly: InternalsVisibleTo(RhinoMocks.StrongName)]
/// Used for [assembly: InternalsVisibleTo(RhinoMocks.NormalName)]
/// </summary>
public static class RhinoMocks
{
/// <summary>
/// Strong name for the Dynamic Proxy assemblies. Used for InternalsVisibleTo specification.
/// </summary>
public const string StrongName =
"DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7";
/// <summary>
/// Normal name for dynamic proxy assemblies. Used for InternalsVisibleTo specification.
/// </summary>
public const string NormalName = "DynamicProxyGenAssembly2";
/// <summary>
/// Logs all method calls for methods
/// </summary>
public static IExpectationLogger Logger = new NullLogger();
}
I've seen a similar issue when using Moq, which has this issue documented.
The problem is that DynamicProxy in Castle needs to dynamically derive a new type but does not have visibility to see your interface which is internal to your assembly. Simply adding the InternalsVisibleTo to the DynamicProxyGenAssembly2 to your test library should solve the problem.
I'm trying to inject specific class into my WCF service but it doesn't work and I can't understand why. I'm VERY NEW to MEF and patterns, just trying to make it work. Watched series of videos to understand what it is about but bootstraping won't work in my case since it is not Silverlight
http://channel9.msdn.com/blogs/mtaulty/mef--silverlight-4-beta-part-1-introduction
Here is my Web application's Global.asax code. This is non MVC, just regular ASP.NET app:
private void Application_Start(object sender, EventArgs e)
{
RegisterRoutes();
var catalog = new WebScopedCatalog(new DirectoryCatalog(Server.MapPath("~\\bin")));
var container = new CompositionContainer(catalog);
container.ComposeParts(this);
}
FIRST, I'm not sure I even bootrstrap it properly.. SECOND, I'm using http://www.timjroberts.com/2011/02/web-scoped-mef-parts/ as a guidance for web-scoped parts. I need that because some injected objects supposed to live during request only.
Now, I have following class:
[Export(typeof(ITest))]
[WebPartCreationPolicy(WebCreationPolicy.Session)]
public class Test : ITest
{
public string TestMe()
{
return "Hello!";
}
}
And my service looks like:
[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class MobileService
{
[Import]
public ITest MyTestClass { get; set; }
public MobileService()
{
int i = 10;
}
When breakpoint hits at i=10 - I have NULL inside MyTestClass. Clearly, MEF does not initialize this class for me. Am I missing something?
EDIT:
When I examine catalog - I see my class Exported but I don't see it imported anywhere...
EDIT 2:
Daniel, Thank you. It makes sense. It still feels litle like a magic for me at this point. Yes, WCF creates this service. Than I have MembershipProvider and various Utility classes that ALL need the same import. And I'm not creating neither of those classes so I can't have Mef creating them. (Service created by WCF, MembershipProvider created by who-knows-what, Utility classes have static methods..) I wanted to use Mef instead of storing my stuff in HttpContext.Current. My container object doesn't have SatisfyImports. It has SatisfyImportsOnce. What if I do it in many different constructors? Will Mef share same singleton or it will be creating new instance every time?
At this point I wonder if I should even use Mef in this particular scenario..
MEF won't satisfy imports for objects it doesn't create. What is it that creates MobileService? If it's not MEF, then the import won't be satisfied by default. Even if it is MEF, the import wouldn't be satisfied in the constructor- you can't set properties on an object you create until it is done being created (ie the constructor has finished).
You can call container.SatisfyImportsOnce(mobileService) to satisfy the imports of a part. You should try to avoid doing this everywhere you need a MEF import. If you can, you should export a part and import it from another part so that MEF handles the creation for you. However, it looks like this part may be created by WCF so you can't have MEF create it, and in that case it would be OK to use SatisfyImportsOnce.
Response to EDIT2: If you use the same container each time, MEF will by default only create one instance of the part with the export. You can set the CreationPolicy to NonShared (in either the export or import attribute) to change this.
As for whether it makes sense to use MEF the way you are trying to, I don't know enough about writing web services to give you any advice on that.
The web-scoped part creation policy that I wrote won't help with WCF services.
I've posted a new blog post that documents an approach to composeable WCF services:
http://www.timjroberts.com/2011/08/wcf-services-with-mef/
Basically, you need to implement a custom Instance Provider that is MEF-aware and can compose the WCF service object when it is created.
I wrote about how to compose your WCF in a generic way that its configuration based here:
Unit Testing, WCF and MEF
I actually built my solution on the code samples Tim Robert's provided in his post. only that I took it a bit further and instead of using code in the global asax i moved the configuration into the web.config so its easier to maintain.
We are running a webforms project at my company and I have an HttpModule that I need to resolve dependencies for.
We use the Ninject.Web library to resolve dependencies for master pages, pages, user controls, web services, and HttpHandlers. All these have base classes you can inherit from in the Ninject.Web Namespace:
MasterPageBase
PageBase
WebServiceBase
HttpHandlerBase
And a custom one we added since for some odd reason it wasn't there: UserControlBase
However I am unable to find a HttpModuleBase. There is a NinjectHttpModule, but that is not a base class, it is a real module that tries to eliminate the need to inherit from base classes in pages and user controls, but it has some bugs and we are not using it.
What is the best way to resolve my dependencies in my HttpModule?
When I google this I come up with this question on the first page -_-
Phil Haack blogged about a way to do this that makes it possible to use constructor injection and thereby avoid making your HttpModule depend directly on Ninject. In a standard NinjectHttpApplication, do the following:
Step 1
Use Nuget to find and add the HttpModuleMagic package to your web project.
Step 2
Write your HttpModule to use constructor injection:
public class MyHttpModule : IHttpModule
{
public MyHttpModule(ISomeService someService) {...}
}
Step 3
Remove the http module from your web.config:
<httpModules>
<!-- Modules will be defined via DI bindings -->
</httpModules>
Step 4
Set up bindings:
Bind<IHttpModule>().To<MyHttpModule>();
// Repeat the pattern above for any other modules.
I'm kind of amazed that nobody has answered this all day! Looks like I stumped you guys :)
Well, I solved the issue. I wrote my own custom implementation of IHttpModule and compiled it into the Ninject.Web assembly myself. Here is the source of the base class I added:
namespace Ninject.Web
{
public class HttpModuleBase : IHttpModule
{
/// <summary>
/// This method is unused by the base class.
/// </summary>
public virtual void Dispose()
{
}
/// <summary>
/// Ininitialize the module and request injection.
/// </summary>
/// <param name="context"></param>
public virtual void Init(HttpApplication context)
{
RequestActivation();
}
/// <summary>
/// Asks the kernel to inject this instance.
/// </summary>
protected virtual void RequestActivation()
{
KernelContainer.Inject(this);
}
}
}
I simply modeled it after the other base classes in the Ninject.Web assembly. It appears to be working wonderfully. Just make your HttpModule inherit from Ninject.Web.HttpModuleBase and then you are free to use property injection within your module, like this:
public class AppOfflineHttpModule : HttpModuleBase
{
[Inject]
public IUtilitiesController utilitiesController { get; set; }
...
}
I'm currently learning how to unit test my methods in a silverlight RIA project. I have some methods that the user is authorized. I though I could solve this problem by creating a mock authorizationservice. And then have the user be authorized in that way, but it seems that I a nullreference from the code because it calls the authorizationservice in the project from which the code I'm testing originates, and gets the nullreference in the createdefaultuser method, which I had otherwise manually overridden in the mockauthorizationservice.
How do I get about this?
My mockauthorization has this namespace/class definitionnamespace
Notlr.Test
{
public class MockAuthentication : AuthenticationService
{
}
}
My Ria authenticationservice looks like this:
namespace Notlr.Web
{
using System;
using System.ServiceModel.DomainServices.Hosting;
using System.ServiceModel.DomainServices.Server.ApplicationServices;
using System.Web.Security;
/// <summary>
/// RIA Services DomainService responsible for authenticating users when
/// they try to log on to the application.
///
/// Most of the functionality is already provided by the base class
/// AuthenticationBase
/// </summary>
[EnableClientAccess]
public class AuthenticationService : AuthenticationBase<User>
{
}
}
Jakob, it sounds like you have namespace issues. Remember that your "test project" in Visual Studio is a Project like any other. It has its own namespace and compiles into its own .net assembly. Having a "test project" does not automatically put the mock objects into the tests; you must write the code to accomplish this on your own.
You need to make sure that you're writing the test code to use the mock authorizationservice when the test runs. If you would like more specific help, please post the code that you're having a problem with.