I created a LoggerDomainService witch look like this :
[EnableClientAccess()]
public class LoggerDomainService : DomainService
{
public void info()
{
// todo
}
}
And after building the server side the LoggerDomainContext did not created.
I've noticed that in order to make it work I need to declare inside the class at least on method with the [Query] attribute.
Is there better way to solver the problem, should I inherit from something else then DomainService ?
You are correct about the [Query] attribute. With your logging service, I recommend using [Invoke]:
[EnableClientAccess()]
public class LoggerDomainService : DomainService
{
[Invoke]
public void info()
{
// todo
}
}
Then you will find the context created.
Related
Is it possible to do something like this?
Query.cs
class Query<T> : ObjectType<MyQuery<T>> where T : class
{
protected override void configure(IObjectTypeDescriptor<MyQuery<T>> descriptor)
{
descriptor
.Field(f => f.GetItems)
.Description("Return List");
}
}
public partial class MyQuery<T> where T : class
{
private readonly IGenericRepositorty _repo
public MyQuery(IGenericRepositorty repo)
{
_repo = repo;
}
public IEnumerable<T> GetItems()
{
return _repo.GetAll(); // GetAll in generic repo
}
}
Now if I am adding my service in Startup.cs as
services.AddQueryType<MyQuery<Entity>>();
It works.
But I want to add it as
services.AddQueryType<MyQuery<>>(); or kind of services.AddQueryType(typeOf(MyQuery<>));
The way we inject generic repo like this
services.AddScoped(typef(IGenericRepository<>),typeofGenericRepository<>)
So, here at run time it creates an instance.
The same way for query at run time I am trying whether it will be possible to create instance
public partial class CTMSEntitiesModel : OpenAccessContext, ICTMSEntitiesModelUnitOfWork
{
public CTMSEntitiesModel(string connection)
:base(connection, backend, metadataSource)
{ }
// there are more IQueryable requests here
}
public interface ICTMSEntitiesContext : ICTMSEntitiesModelUnitOfWork
{
FetchStrategy FetchStrategy { get; set; }
}
public interface ICTMSEntitiesModelUnitOfWork : IUnitOfWork
{
//all the IQueryable requests are here
}
I need to bind the ICTMSEntitiesContext to CTMSEntitiesModel. How would I go about doing that? What am I doing wrong when I do this? It is throwing an InvalidCastException.
kernel.Bind(typeof(CTMSDAL.ICTMSEntitiesContext)).To(typeof(CTMSDAL.CTMSEntitiesModel)).InRequestScope()
.WithConstructorArgument("connection", System.Configuration.ConfigurationManager.ConnectionStrings["CTMS_MVCConnection"].ConnectionString);
I would appreciate all the help you can provide!
Thanks,
Safris
You have to implement the ICTMSEntitiesContext in the CTMSEntitiesModel class. Otherwise there is no way to cast an instance of the class to the target interface.
Given that you are using OpenAccess and the fact that the context class may be automatically generated I would suggest to you add the interface implementation into a new partial class in different project file to avoid losing the custom code after the original file is regenerated:
public partial class CTMSEntitiesModel : ICTMSEntitiesContext
{
// FetchStrategy property is already defined
}
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
What I'm trying to do is the following:
1) I have the following WCF service contract:
[ServiceContract]
public interface IUploadService
{
[OperationContract]
ServiceData Upload(Request request);
}
[DataContract]
public class Request
{
[DataMember]
public long AbnNumber;
[DataMember]
public string Email;
}
2) This contract is implemented like this.
public class UploadService : IUploadService
{
public bool Upload(Request request)
{
// Some code
}
}
In the "Some code" section I would like to call a validation class to validate the clients request, so something like this:
var result = validation.ValidateRequest(request);
So my question is: Is it a bad idea to create an instance of my validation class inside the Upload method? Like this:
public class UploadService : IUploadService
{
public bool Upload(Request request)
{
var validation = new Validation();
var result = validation.ValidateRequest(request);
}
}
I know you can get around this by creating a constructor but as far as I know you can't create a constructor inside a WCF service implementation class, or am I wrong?
I'm new to WCF so if I'm totally heading the wrong direction please let me know.
Thanks
Personally I like as little as possible in my service methods. I would have a separate project to handle the Upload. This then allows you to reuse this code more easily, and to test the functionality without creating the service.
As to whether you should create your Validation like this it really depends on what it does, but generally I would make sure the Validation class implements an interface containing ValidateRequest(Request) and then inject that. You can then mock it in your tests if you need to.
So your service code would look like
public class UploadService : IUploadService
{
private readonly IUploadHandler _uploadHandler;
public UploadService(IUploadHandler uploadHandler)
{
_uploadHandler = uploadHandler;
}
public bool Upload(Request request)
{
//would possibly do some mapping here to create a different type of object to pass to the handler
_uploadHandler.Upload(request);
}
}
and the handler in a different project would look like
public class UploadHandler : IUploadHandler
{
private readonly IValidation _validator;
public UploadHandler(IValidation validator)
{
_validator = validator;
}
public bool Upload(Request request)
{
return _validator.ValidateRequest(request);
}
}
So my question is: Is it a bad idea to create an instance of my validation class inside the Upload method?
It comes down to whether you will be using Singleton or Per Call services. Usually it is better to have new instance of Service created for every request, and in that case it is OK to create all instances in your operation.
Interesting discussion on this topic Should WCF service typically be singleton or not?
If you decide to not to create Validation class for each then request there are two options:
Make it singleton
Create custom ServiceHostFactory for your service and initialize your Service in it (with constructor). Useful links on this topic:Extending Hosting Using ServiceHostFactory, Integrating StructureMap with WCF
I've been trying to get the ninject working in wcf, using the wcf extension and the interception with dynamicproxy2 extension. I've basically created a Time attribute and have it all working in a basic scenario. Where I get trouble is when in ninject module I create my service binding with a constructor argument:
Bind<IMyDependency>().To<MyDependency>();
Bind<IService1>().To<Service1>().WithConstructorArgument("dependency", Kernel.Get<IMyDependency>());
Everything works fine, but the Time attribute wont fire on anything in my Service1 or MyDependency.
The time attribute is the standard one floating all over the internet. The only other piece of code really is the CreateKernel method is the global.asax, which looks like this:
protected override IKernel CreateKernel() {
IKernel kernel = new StandardKernel(
new NinjectSettings() { LoadExtensions = false },
new WcfNinjectModule(),
new DynamicProxy2Module()
);
return kernel;
}
Thanks for any help!
Matt
EDIT 12/12/2011: As requested, I've added some more detail below:
The entire wcf ninject module:
public class WcfNinjectModule : NinjectModule
{
public override void Load()
{
Bind<IMyDependency>().To<MyDependency>();
Bind<IService1>().To<Service1>();
}
}
The create kernel method in the global.asax is above, and the global.asax inherits from NinjectWcfApplication.
Service method looks like this:
public class Service1 : IService1
{
private IMyDependency _dependency;
public Service1()
{
}
public Service1(IMyDependency dependency)
{
_dependency = dependency;
}
[Time]
public virtual string GetData(string value)
{
return string.Format(_dependency.GetMyString(), value);
}
}
public interface IMyDependency
{
string GetMyString();
}
public class MyDependency : IMyDependency
{
[Time]
public virtual string GetMyString()
{
return "Hello {0}";
}
}
Does this help?
Since removing the 'WithConstructor' argument, the time intercept attribute will fire on GetMyString but not on GetData.
Matt
After a little more work (and writing that last post edit), it turns out that just removing the WithConstructorArgument method did resolve my problem and everything now seems to be working fine.
Matt