c# – 如何将Fitnesse与Autofac / IOC集成?
当Fitnesse实例化一个fixture时,它会查找默认的公共构造函数.
但是,我想构造函数注入我想要在fixture中使用的任何应用程序服务. 即我想写这个夹具…… public class MyColumnFixture : ColumnFixture { private readonly IApplicationService _applicationService; public ManualExitSetupFixture(IApplicationService applicationService) { _applicationService = applicationService; } public void DoStuff(string arg1) { _applicationService.DoStuff(arg1); } } 到目前为止,我设法提出的最好的方法是将容器暴露为单例(见下文).但必须有更好的方法. Autofac与我们使用的许多其他技术完美集成. public class AutofacIntegration { private static IContainer _container; public static IContainer Container { get { if (_container == null) { var builder = new ContainerBuilder(); builder.RegisterModule<MyApplicationModule>(); _container = builder.Build(); } return _container; } } } public class MyColumnFixture : ColumnFixture { private readonly IApplicationService _applicationService; public ManualExitSetupFixture() { _applicationService = AutofacIntegration.Container.Resolve<IApplicationService>(); } public void DoStuff(string arg1) { _applicationService.DoStuff(arg1); } } 编辑:包括更多细节,我试图在Mike的帮助下完成这项工作…… 我创建了一个类,它是从Fitsharp反编译的CreateDefault的反编译代码中复制粘贴的… public class CreateDefault<T,P> : Operator<T,P>,CreateOperator<T> where P : class,Processor<T> { public bool CanCreate(NameMatcher memberName,Tree<T> parameters) { return true; } public TypedValue Create(NameMatcher memberName,Tree<T> parameters) { ... } } …并在SuiteConfig.xml中注册了这个… <suiteConfig> <ApplicationUnderTest> <AddAssembly>....ServicesWinMyProj.FitnesseMyProj.FitnessebinDebugMyProj.Fitnesse.dll</AddAssembly> </ApplicationUnderTest> <Fit.Operators> <Add>MyProj.Fitnesse.CreateDefault`2</Add> </Fit.Operators> </suiteConfig> …这会在尝试加载我的CreateDefault<,>时出现以下异常类. System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> fitSharp.Machine.Exception.CreateException: Constructor with 0 parameter(s) failed for type 'MyProj.Fitnesse.CreateDefault`2'. ---> System.ArgumentException: Cannot create an instance of MyProj.Fitnesse.CreateDefault`2[T,P] because Type.ContainsGenericParameters is true. at System.RuntimeType.CreateInstanceCheckThis() at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr,Binder binder,Object[] args,CultureInfo culture,Object[] activationAttributes,StackCrawlMark& stackMark) at System.Activator.CreateInstance(Type type,BindingFlags bindingAttr,Object[] activationAttributes) at System.Reflection.Assembly.CreateInstance(String typeName,Boolean ignoreCase,Object[] activationAttributes) at fitSharp.Machine.Engine.RuntimeType.CreateInstance() at fitSharp.Machine.Engine.CreateDefault`2.CreateWithoutParameters(RuntimeType runtimeType) --- End of inner exception stack trace --- at fitSharp.Machine.Engine.CreateDefault`2.CreateWithoutParameters(RuntimeType runtimeType) at fitSharp.Machine.Engine.CreateDefault`2.Create(NameMatcher memberName,Tree`1 parameters) --- End of inner exception stack trace --- at System.RuntimeMethodHandle.InvokeMethod(Object target,Object[] arguments,Signature sig,Boolean constructor) at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj,Object[] parameters,Object[] arguments) at System.Reflection.RuntimeMethodInfo.Invoke(Object obj,BindingFlags invokeAttr,CultureInfo culture) at System.RuntimeType.InvokeMember(String name,BindingFlags bindingFlags,Object target,Object[] providedArgs,ParameterModifier[] modifiers,String[] namedParams) at fitSharp.Machine.Engine.MethodMember.TryInvoke(Object[] parameters) at fitSharp.Machine.Engine.ReflectionMember.Invoke(Object[] parameters) at fitSharp.Machine.Engine.ProcessorBase`2.Operate[O](Object[] parameters) at fitSharp.Machine.Engine.Operators`2.Add(String operatorName) --- End of inner exception stack trace --- at fitSharp.Machine.Engine.ProcessorExtension.InvokeWithThrow[T](Processor`1 processor,TypedValue instance,MemberName memberName,Tree`1 parameters) at fitSharp.Machine.Application.SuiteConfiguration.LoadNode(String typeName,XmlNode methodNode) at fitSharp.Machine.Application.SuiteConfiguration.LoadXml(String configurationXml) at fitSharp.Machine.Application.ArgumentParser.InvokeArgumentHandler(String switch,String argumentValue) at fitSharp.Machine.Application.ArgumentParser.Parse(IList`1 commandLineArguments) at fitSharp.Machine.Application.Shell.Run(IList`1 commandLineArguments) 编辑:非常感谢迈克,现在正在努力享受. 实现非常简单,我确信它可以改进,但这里有一个快速的方法… >定义自定义CreateOperator 我的CreateOperator代码…… public class AutofacCreateOperator : CellOperator,CreateOperator<Cell> { private static IContainer _container; public AutofacCreateOperator() { var builder = new ContainerBuilder(); builder.RegisterModule<FitnesseModule>(); _container = builder.Build(); } public bool CanCreate(NameMatcher memberName,Tree<Cell> parameters) { return _container.ComponentRegistry.IsRegistered(new TypedService(Type.GetType(memberName.MatchName))); } public TypedValue Create(NameMatcher memberName,Tree<Cell> parameters) { return new TypedValue(_container.Resolve(Type.GetType(memberName.MatchName))); } } 解决方法
这可以完成 – 您需要编写一个自定义类来处理fitSharp的创建操作.它将实现此接口:
public interface CreateOperator<T> { bool CanCreate(NameMatcher memberName,Tree<T> parameters); TypedValue Create(NameMatcher memberName,Tree<T> parameters); } 然后告诉fitSharp在套件配置文件中使用此类: <suiteConfig> <Fit.Operators> <Add>My.Create.Operator</Add> </Fit.Operators> ... </suiteConfig> 作为一个说明点,这是一个非常简单的创建运算符.你可以修改它来进行AutoFac注入. public class TestCreateOperator: CellOperator,CreateOperator<Cell> { public bool CanCreate(NameMatcher memberName,Tree<Cell> parameters) { return memberName.Matches("testname"); } public TypedValue Create(NameMatcher memberName,Tree<Cell> parameters) { return new TypedValue("mytestname"); } } 仅供参考,这是内置类,用于创建夹具. public class CreateDefault<T,P>: Operator<T,CreateOperator<T> where P: class,Processor<T> { public bool CanCreate(NameMatcher memberName,Tree<T> parameters) { return true; } public TypedValue Create(NameMatcher memberName,Tree<T> parameters) { var runtimeType = Processor.ApplicationUnderTest.FindType(memberName); return parameters.Branches.Count == 0 ? CreateWithoutParameters(runtimeType) : CreateWithParameters(parameters,runtimeType); } static TypedValue CreateWithoutParameters(RuntimeType runtimeType) { try { return runtimeType.CreateInstance(); } catch (System.Exception e) { throw new CreateException(runtimeType.Type,e.InnerException ?? e); } } TypedValue CreateWithParameters(Tree<T> parameters,RuntimeType runtimeType) { RuntimeMember member = runtimeType.GetConstructor(parameters.Branches.Count); object[] parameterList = new ParameterList<T>(Processor).GetParameterList(TypedValue.Void,parameters,member); try { return member.Invoke(parameterList); } catch (System.Exception e) { throw new CreateException(runtimeType.Type,parameterList.Length,e.InnerException ?? e); } } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- ruby-on-rails – Authlogic:生成“已经发送电子邮件”错误
- c# – 无法更改目标框架?
- postgresql – ALTER ROLE与CREATEDB和GRANT CREATE ON TAB
- Sqlite的操作(增加,删除,查询,修改)
- objective-c – 使用atos通过dSYM确定崩溃的方法名称
- arrays – 在Array中搜索字符串,不区分大小写
- 传递给C函数的数组给出了不同的长度
- Oracle修改监听IP地址
- 使用Xml类下的newPullParser ()、newSerializer ()方法,解
- 切记ajax中要带上AntiForgeryToken防止CSRF攻击