WcfTestClient method take base class as param - wcf

I have the following method signature being exposed via WCF:
public void MethodA(RequestBase request)
{
}
public class RequestA : RequestBase
{
}
There are some concrete classes derived from the RequestBase Class. During the service call using WcfTestClient.exe, how do i pass the actual concrete class (RequestA) to the RequestBase in methodA ?

You're looking for the KnownType attribute for your data contracts:
[DataContract]
public class RequestBase
{
}
[DataContract]
[KnownType(typeof(RequestBase))]
public class RequestA : RequestBase
{
}
Then you can pass in a RequestA object where RequestBase is the expected type of the service operation:
var requestA = new RequestA();
serviceClient.MethodA(requestA);

Related

How can I get HttpContext inside an abstract class in ASPNETCore

I have the following Repository:
public class TestRepository : WebCaller<Data>, ITestRepository
{
string connString = this.GetConnectionString();
.... some code here
}
In my Repository I can do Dependency Injection to the constructor without a problem.
In my abstract class WebCaller I need to get access to HttpContext somehow, I was reading that you can Inject IHttpContextAccessor to get access to the context, but because this is an Abstract class, that also lives outside the Web project, I can't have a constructor.
I was trying to do this:
public abstract class WebCaller<T> : WebRequest, IDisposable
{
//[Inject]
public ITestRepository TestRepo
{
get
{
return this.HttpContext.RequestServices.GetRequiredService<ITestRepository >();
}
}
..... more code here
}
Was trying to use Inject attribute but was reading that is no longer available, so should be other way to pass HttContext to the abstract class.
You can have a constructor on your abstract class. Just inject IHttpContextAccessor to it. Then any derived class will also take IHttpContextAccessor and pass it to its base constructor (your abstract class constructor). You can make the abstract class constructor protected.
Like:
public abstract class WebCaller<T> : WebRequest, IDisposable
{
protected WebCaller(IHttpContextAccessor contextAccessor)
{
}
}
public class TestRepository : WebCaller<Data>, ITestRepository
{
public TestRepository(IHttpContextAccessor contextAccessor) : base(contextAccessor)
{
}
string connString = this.GetConnectionString();
.... some code here
}

Ninject factory method with input parameter to determine which implementation to return

I am trying to find a way to have a factory class / method that would take in an object or some kind of identifier (string or type) then based off the input parameter determine which implementation of the interface to create and return.
how do I setup my factory method and register the dependency for the interface? following is what I have roughly.
public class ISampleFactory
{
public ISample GetSample(Type type)
{
// do something here to return an implementation of ISample
}
}
public class SampleA : ISample
{
public void DoSomething();
}
public class SampleB : ISample
{
public void DoSomething();
}
public interface ISample
{
void DoSomethin();
}
Have a look at ninject Contextual Bindings Documentation:
You can either use Named Bindings:
this.Bind<ISample>().To<SampleA>().Named("A");
this.Bind<ISample>().To<SampleB>().Named("B");
or a conditional binding with any of the already available extensions or write your own:
this.Bind<ISample>().To<SampleA>().When(...);
this.Bind<ISample>().To<SampleB>().When(...);
see https://github.com/ninject/ninject/wiki/Contextual-Binding

How to make WCF data interface serializable

I have a WCF service and one method accepts an interface IValidationDictionary when calling the service I need to access the interface but the VS generated proxy class shows the interface as an object. I tried to add data attributes to the interface but that is not allowed.
Thanks in advance.
public class UserService : IUserService
{
private IValidationDictionary validatonDictionary;
private IUserAppService userAppService;
public UserService(IUserAppService userAppService)
{
this.userAppService = userAppService;
}
public void SetValidation(IValidationDictionary validationDictionary)
{
this.validatonDictionary = validationDictionary;
}
public UserDTO GetUser(int id)
{
return this.userAppService.GetUser(id);
}
}
public interface IValidationDictionary
{
void AddError(string key, string errorMessage);
bool IsValid();
}
Interfaces can not be serialize, but you can return any object which implements that interface.

Poison message when reading queue of known type

I was able to get this working for different projects and believe im following the same path/pattern but something is missing.
I keep getting a poison message when I send a message of a known type on the MSMQ.
I have a class called ConcreteClass which has several properties, decorated with DataMember attributes. I have a "Base" class which the ConcreteClass derives from.
I can send the message to the MSMQ fine but when reading from the MSMQ using WCF, the service always faults and looking at the logs, it is a poison message.
the WCF service is using the base class as the signature (which worked fine in a different project) and has serviceknowntype attributes decorated for the concrete classes the service should expect.
[ServiceKnownType(typeof(ConcreteClass))]
public sealed class WCFServiceMSMQReader : IWCFServiceMSMQReader {
[OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
public void ProcessIncomingMessage(MsmqMessage<BaseClass> msg) { .... do stuff .... }
}
interface:
[ServiceContract]
public interface IWCFServiceMSMQReader {
[OperationContract(IsOneWay = true, Action = "*")]
void ProcessIncomingMessage(MsmqMessage<BaseClass> msg);
}
BaseClass:
[DataContract]
[KnownType(typeof(ConcreteClass))]
public class BaseClass
{
... some properties here...
}
ConcreteClass:
[DataContract]
public class ConcreteClass : BaseClass {
public ConcreteClass() : base() { ... stuff ... }
public ConcreteClass(params here) : base() { .... }
}
any ideas where I am going wrong?
The service known types should be declared in the interface

kernel.Get to get singleton instance

I have ConverterTest class where I need to access ValidateTest class. I can't pass ValidateTest using constructor because ConverterTest is abstract class. If I introduce second constructor to bind ValidateTest I will get numerous problems in derived classes and many things will need to change. So I have tried to pass ValidateTest to ConverterTest using property injection(decorated with inject attribute) but that also do not work because ConverterTest is not created by Ninject and inject properties are ignored. So I decided to create Instance property directly in ValidateTest class and bind instance of itself. To get instance of ValidateTest in ConverterTest class I use kernel.Get<ValidateTest>().Instance. Everything works fine but is it good idea to use kernel.Get to access instance class? Is there any other solution?
public class ValidateTest
{
private readonly ISettingsRepository _settingsRepository;
[Inject]
public ValidateTest Instance { get; set; }
public ValidateTest(ISettingsRepository settingsRepository)
{
_settingsRepository = settingsRepository;
}
}
Binding
kernel.Bind<ISettingsRepository>().To<SettingsRepository>();
kernel.Bind<ValidateAbuse>().ToSelf().InSingletonScope();
Getting instance of ValidateTest using kernel.Get in abstract class where constructor binding is not possible and property binding is not working.
public abstract class ConverterTest
{
public void Execute()
{
NinjectHelper.kernel.Get<ValidateTest>().Instance
}
}
Why not have your subclasses of ConverterTest set the ValidateTest either via an exposed property in ConverterTest or constructor's of their own?
public abstract class ConverterTest
{
protected ValidateTest ValidateTest{get;set;}
public void Execute()
{
ValidateTest.ValidateStuff();
}
}
public class ConcreteConverter : ConverterTest
{
[Inject]
public ConcreteConverter(ValidateTest validateTest)
{
base.ValidateTest = validateTest;
}
}
Or, I think that you could make the property public public ValidateTest ValidateTest{get;set;} and it should work for property injection if you add the appropriate attribute.
public abstract class ConverterTest
{
[Inject]
public ValidateTest ValidateTest{get;set;}
public void Execute()
{
ValidateTest.ValidateStuff();
}
}