在MS Unity (App Block)中复制对象名称

本文关键字:复制 对象 Block MS Unity App | 更新日期: 2023-09-27 18:03:34

我会尽量让它变得简单!

对于Unity注册部分:

// ====================================================================
// NOTE:  This fails as the WithName.TypeName is Payload for all jobs!  
// HOW can we make the name for payloads "[JobName].Payload"??
// ====================================================================
_container.RegisterTypes(AllClasses.FromAssembliesInBasePath()
    .Where(type => (typeof(IJob).IsAssignableFrom(type) || typeof(IJobPayload).IsAssignableFrom(type)) && type.IsClass),
    WithMappings.FromAllInterfaces,
    WithName.TypeName,
    WithLifetime.Transient);

地点:

public interface IJob
{
    bool Execute<T>(T payload) where T : class, IJobPayload;
}
public interface IJobPayload
{
    string JobName { get; set; }
    string JobQueueName { get; set; }
    int Id { get; set; }
    JobType JobType { get; set; }
    CronExpression Cron { get; set; }
}

现在我们可以建立各种工作。比如:

public class Job1 : IJob
{
    bool IJob.Execute<T>(T payload)
    {
        if (typeof(T) != typeof(Payload))
            throw new ArgumentException($"Expecting an object with a type of {typeof(Payload)}!");
        Console.WriteLine("public class Job1 : IJob");
        return false;
    }
    public class Payload : IJobPayload
    {
        public string JobName { get; set; }
        public string JobQueueName { get; set; }
        public int Id { get; set; }
        public JobType JobType { get; set; }
        public CronExpression Cron { get; set; }
        // --- job specific data -------------------
        public string Job1ExtraData { get; set }
        public datetime Job1Created { get; set }
    }
}
public class Job2 : IJob
{
    bool IJob.Execute<T>(T payload)
    {
        if (typeof(T) != typeof(Payload))
            throw new ArgumentException($"Expecting an object with a type of {typeof(Payload)}!");
        Console.WriteLine("public class Job2 : IJob");
        return false;
    }
    public class Payload : IJobPayload
    {
        public string JobName { get; set; }
        public string JobQueueName { get; set; }
        public int Id { get; set; }
        public JobType JobType { get; set; }
        public CronExpression Cron { get; set; }
        // --- job specific data -------------------
        public string Title { get; set }
        public int Count { get; set }
    }
}

当试图解决Job1.PayloadJob2.Payload的具体类时,问题就出现了。两者在Unity中都有相同的名称:Payload !

由于我正在工作的项目有很多,很多的工作,我们想建立一个模板来创建新的工作(添加>工作),我们更喜欢有工作的子负载模型。

现在我有控制器代码,在一个JSON表示的Payload对象:

[HttpPost]
public void Post(dynamic json)
{
    var container = UnityHelpers.GetConfiguredContainer();
    var jobName = GetJobNameFromJson(json); // JsonConverter will not work until I can resolve *which* payload definition I want, brute force it for now...
    var job = container.Resolve<IJob>(jobName);
    // ====================================================================
    // how do I get it to a point where this will resolve.
    // (see original NOTE at top of question)
    // ====================================================================
    var payload = container.Resolve(typeof(IJobPayload), $"{jobName}.Payload");
    job.Execute(payload);
}

我如何在Unity(或任何其他IoC容器)中使用这个?

在MS Unity (App Block)中复制对象名称

您正在使用的RegisterTypes的过载的第三个参数是Func<Type,string>类型的。RegisterTypes方法将为它找到的每个类型调用此委托,以获得注册的名称。

WithName.TypeName只是一个返回类型名称的静态方法。

您可以创建自己的方法或lambda表达式,它们足够智能,可以检测类型是否为嵌套类型。下面是一个例子:

t => t.IsNested ? t.DeclaringType.Name + "." + t.Name : t.Name

那么你的注册语句应该是这样的:

_container.RegisterTypes(
    AllClasses.FromAssembliesInBasePath()
        .Where(type => (typeof(IJob).IsAssignableFrom(type) || typeof(IJobPayload).IsAssignableFrom(type)) && type.IsClass),
    WithMappings.FromAllInterfaces,
    t => t.IsNested ? t.DeclaringType.Name + "." + t.Name : t.Name,
    WithLifetime.Transient);