Dependence injection into generic class - c#-4.0

I have generic Result<T> generic class which I use often in methods to return result like this
public Result<User> ValidateUser(string email, string password)
There is ILoggingService interface in Result class for logging service injection but I do not find a way to inject actual implementation.
I tried to execute the code below but TestLoggingService intance is not injected into LoggingService property. It always return null. Any ideas how to solve it?
using (var kernel = new StandardKernel())
{
kernel.Bind<ILoggingService>().To<TestLoggingService>();
var resultClass = new ResultClass();
var exception = new Exception("Test exception");
var testResult = new Result<ResultClass>(exception, "Testing exception", true);
}
public class Result<T>
{
[Inject]
public ILoggingService LoggingService{ private get; set; } //Always get null
protected T result = default(T);
//Code skipped
private void WriteToLog(string messageToLog, object resultToLog, Exception exceptionToLog)
{
LoggingService.Log(....); //Exception here, reference is null
}

You are creating the instance manually using new. Ninject will only inject objects created by kernel.Get(). Furthermore it seems you try to inject something into a DTO which is not recommended. Better do the the logging in the class that created the result:
public class MyService
{
public MyService(ILoggingService loggingService) { ... }
public Result<T> CalculateResult<T>()
{
Result<T> result = ...
_loggingService.Log( ... );
return result;
}
}

Related

Is it normal to return actor's proxy from service

I have some service which accepts some data and then, as I think, should return an actor initialized with some values.
public class MyService : StatefulService, IMyService
{
public IMyActor DoThings(Data data)
{
var actor = ActorProxy.Create<IMyActor>(new ActorId(Guid.NewGuid()));
actor.Init(data);
//some other things
return actor;
}
}
Another service would do this:
var service = ServiceProxy.Create<ICommandBrokerService>(new Uri("fabric:/App"), ServicePartitionKey.Singleton);
var actor = service.DoThings(data);
var state = actor.GetState();
//...
So, is it okay to return an actor in such a way, or should I return actor's id and request a proxy on a call sight?
UPD:
According to a #LoekD 's answer I did a wrapper to be a little type-safety.
[DataContract(Name = "ActorReferenceOf{0}Wrapper")]
public class ActorReferenceWrapper<T>
{
[DataMember]
public ActorReference ActorReference { get; private set; }
public ActorReferenceWrapper(ActorReference actorRef)
{
ActorReference = actorRef ?? throw new ArgumentNullException();
}
public T Bind()
{
return (T)ActorReference.Bind(typeof(T));
}
public IActorService GetActorService(IActorProxyFactory serviceProxy=null)
{
return ActorReference.GetActorService(serviceProxy);
}
public TService GetActorService<TService>(IActorProxyFactory serviceProxyFactory) where TService : IActorService
{
return serviceProxyFactory.CreateActorServiceProxy<TService>(ActorReference.ServiceUri,
ActorReference.ActorId);
}
public static implicit operator ActorReference(ActorReferenceWrapper<T> actorRef)
{
return actorRef.ActorReference;
}
public static explicit operator ActorReferenceWrapper<T>(ActorReference actorReference)
{
return new ActorReferenceWrapper<T>(actorReference);
}
}
No, the types used in SF remoting must be DataContractSerializable. The contracts you use can only have fields and properties, no methods.
So, instead of returning the proxy, return an Actor Reference.
Next, use Bind to create a proxy from it.

ASP.NET using UrlHelper in ViewModel

I'm trying to strongly type (such as it is) some URLs for a web app when I build a viewmodel.
So I have something like:
new MyModel {
Text = "Foo",
Url = new UrlHelper(Request.RequestContext).Action("MyAction")
}
This works just fine in a controller method, but I have another situation where I am not receiving the Request.Context because it's being called in another class.
Is there another way to do this so that I'm not using "magic strings" and/or relying on the context object?
Use Reference
HttpContext.Current
which is derived from system.web. There for following code will work anywhere in your application.
UrlHelper objUrlHelper = new UrlHelper(HttpContext.Current.Request.RequestContext);
objUrlHelper.Action("About");
Example:
public class MyViewModel
{
public int ID { get; private set; }
public string Link
{
get
{
UrlHelper objUrlHelper = new UrlHelper(HttpContext.Current.Request.RequestContext);
return objUrlHelper.Action("YourAction", "YourController", new { id = this.ID });
}
}
public MyViewModel(int id)
{
this.ID = id;
}
}

How is IClock resolved with SystemClock in this example?

I am trying to learn IOC principle from this screencast
Inversion of Control from First Principles - Top Gear Style
I tried do as per screencast but i get an error while AutomaticFactory try create an object of AutoCue. AutoCue class has contructor which takes IClock and not SystemClock. But my question is , in screencast IClock is resolved with SystemClock while inside AutomaticFactory .But in my code , IClock does not get resolved . Am i missing something ?
class Program
{
static void Main(string[] args)
{
//var clarkson = new Clarkson(new AutoCue(new SystemClock()), new Megaphone());
//var clarkson = ClarksonFactory.SpawnOne();
var clarkson = (Clarkson)AutomaticFactory.GetOne(typeof(Clarkson));
clarkson.SaySomething();
Console.Read();
}
}
public class AutomaticFactory
{
public static object GetOne(Type type)
{
var constructor = type.GetConstructors().Single();
var parameters = constructor.GetParameters();
if (!parameters.Any()) return Activator.CreateInstance(type);
var args = new List<object>();
foreach(var parameter in parameters)
{
var arg = GetOne(parameter.ParameterType);
args.Add(arg);
}
var result = Activator.CreateInstance(type, args.ToArray());
return result;
}
}
public class Clarkson
{
private readonly AutoCue _autocue;
private readonly Megaphone _megaphone;
public Clarkson(AutoCue autocue,Megaphone megaphone)
{
_autocue = autocue;
_megaphone =megaphone;
}
public void SaySomething()
{
var message = _autocue.GetCue();
_megaphone.Shout(message);
}
}
public class Megaphone
{
public void Shout(string message)
{
Console.WriteLine(message);
}
}
public interface IClock
{
DateTime Now { get; }
}
public class SystemClock : IClock
{
public DateTime Now { get { return DateTime.Now; } }
}
public class AutoCue
{
private readonly IClock _clock;
public AutoCue(IClock clock)
{
_clock = clock;
}
public string GetCue()
{
DateTime now = _clock.Now;
if (now.DayOfWeek == DayOfWeek.Sunday)
{
return "Its a sunday!";
}
else
{
return "I have to work!";
}
}
}
What you basically implemented is a small IoC container that is able to auto-wire object graphs. But your implementation is only able to create object graphs of concrete objects. This makes your code violate the Dependency Inversion Principle.
What's missing from the implementation is some sort of Register method that tells your AutomaticFactory that when confronted with an abstraction, it should resolve the registered implementation. That could look as follows:
private static readonly Dictionary<Type, Type> registrations =
new Dictionary<Type, Type>();
public static void Register<TService, TImplementation>()
where TImplementation : class, TService
where TService : class
{
registrations.Add(typeof(TService), typeof(TImplementation));
}
No you will have to do an adjustment to the GetOne method as well. You can add the following code at the start of the GetOne method:
if (registrations.ContainsKey(type))
{
type = registrations[type];
}
That will ensure that if the supplied type is registered in the AutomaticFactory as TService, the mapped TImplementation will be used and the factory will continue using this implementation as the type to build up.
This does mean however that you now have to explicitly register the mapping between IClock and SystemClock (which is a quite natural thing to do if you're working with an IoC container). You must make this mapping before the first instance is resolved from the AutomaticFactory. So you should add the following line to to the beginning of the Main method:
AutomaticFactory.Register<IClock, SystemClock>();

Accessing the calling Service from ServiceRunner?

I want to access the calling Service from inside the ServiceRunner OnBeforeRequest()method in order to get to an object in the calling service class. In MVC, I can create a class BaseController that overrides OnActionExecuting() and I can get to Data easily. However, using ServiceRunner, since it's not derived from Service, I don't see a way to get to the Service object.
Sample service:
public class ProductsService : Service
{
private MyData _data = new MyData();
public MyData Data
{
get { return _data; }
}
public object Get(GetProduct request)
{
// ...
return product;
}
}
In my custom ServiceRunner, how do I retrieve the ProductsService object from OnBeforeRequest() so I can get to Data?
public class MyServiceRunner<T> : ServiceRunner<T>
{
public override void OnBeforeExecute(IRequestContext requestContext, T request)
{
// var productService = ?
base.OnBeforeExecute(requestContext, request);
}
}
After much digging, it looks like this cannot be done. The Service action is available in the ServiceRunner as an unnamed lamdba delegate. There is no reference to the Service.
I have instead found a workaround. I first registered MyData in AppHost.Configure() using
container.RegisterAutoWired<MyData>();
I moved the MyData declaration to a filter attribute like this:
public class UseMyDataAttribute : RequestFilterAttribute
{
public MyData Data { get; set; } // injected by Funq IoC.
public override void Execute(IHttpRequest req, IHttpResponse res, object responseDto)
{
Data.SessionID = req.GetSessionId();
}
}
This way I can apply [UseMyData] to the ProductsService class and be able to set the Session ID to Data.

How do I access a derived class value from a base class static method?

Here is a sample of what I am trying to accomplish:
public class BaseClass<T>
{
public static T GetByID(int ID)
{
// Need database name here that is determined at design time in the derived class.
var databaseName = "";
// do some stuff involving database name that gets me object by ID here.
return default(T);
}
}
public class DerivedClass : BaseClass<DerivedClass>
{
private string DatabaseName { get; set; }
}
Basically, how would I access the derived "DatabaseName" in the base class static GetByID method?
EDIT: After I posted this, I tried one more thing. I played with attributes earlier, and failed, but I think my brain was mushy. Just tried again and ran a test, and it is working. Here is the updated sample.
public class BaseClass<T>
{
public static T GetByID(int ID)
{
// Need database name here that is determined at design time in the derived class.
var databaseName = ((DatabaseAttribute)typeof(T).GetCustomAttributes(typeof(DatabaseAttribute), true).First()).DatabaseName;
// do some stuff involving database name that gets me object by ID here.
return default(T);
}
}
[Database("MyDatabase")]
public class DerivedClass : BaseClass<DerivedClass>
{
}
public class DatabaseAttribute : Attribute
{
public DatabaseAttribute(string databaseName)
{
DatabaseName = databaseName;
}
public string DatabaseName { get; set; }
}
Base class to derived class is a one-way inheritance: The base class has no knowledge of the existance of a derived class, and so it can't access it.
In addition to that you will have a hard time accessing a non-static property from a static method.
I know you've already answered your own question, but some improvements....
Add a where clause to guarantee inheritance, it means any static methods can make use of inherited methods. You might also want to add the new() clause if you wish to be able to create instances of the inherited class.
public class BaseClass<T> : where T : BaseClass<T>
{
static readonly string databaseName;
static BaseClass() {
// Setup database name once per type of T by putting the initialization in
// the static constructor
databaseName = typeof(T).GetCustomAttributes(typeof(DatabaseAttribute),true)
.OfType<DatabaseAttribute>()
.Select(x => x.Name)
.FirstOrDefault();
}
public static T GetByID(int ID)
{
// Database name will be in the static field databaseName, which is unique
// to each type of T
// do some stuff involving database name that gets me object by ID here.
return default(T);
}
}
[Database("MyDatabase")]
public class DerivedClass : BaseClass<DerivedClass>
{
}
public class DatabaseAttribute : Attribute
{
public DatabaseAttribute(string databaseName)
{
DatabaseName = databaseName;
}
public string DatabaseName { get; set; }
}

Resources